在 FoxOne 1.5.1 版更新中,打开各个交易所网页的速度得到了巨大提升。
我们分别在不同的网络环境下,测算了新版 FoxOne 在 Dom 加载和页面加载条件下的所需时间:
可以看到,无论是 DOM 加载速度还是 Page 加载速度,新方案都有不同程度的提升(从 9% ~ 31%)。我们是怎么做到的呢?
Webview
的问题
FoxOne 的桌面版本使用了 Electron + Electron Builder + Vue 作为技术栈。Electron 是使用 Web 技术构建桌面 App 的框架,而 Electron Builder 则为 Electron 提供了打包、签名、跨平台 CI、自动更新的全家桶方案。
我们当初选择 Electron,是因为 Web 技术会为 FoxOne 开发提供了很多便利,但由于 Electron 项目对 Chromuim 的依赖,在 Chromuim 上游的一些问题也就无缝平移到了 Electron。其中的典型就是 <webview>
webview
可以看作一个跑在独立进程中的更安全的 iframe。如果我们需要在 Electron App 中嵌入一个网页(而不是在新窗口中打开),把它放在 webview
中是官方建议的标准做法,很多著名桌面软件也在使用它。
最初,FoxOne 也在使用 webview
,并且最初看来功能安好。但是很快我们就发现了问题:
一、虽然 webview
跑在独立进程中,但是在 DOM 结构上与 Renderer 进程同源,因此渲染 webview
时会拖累整个 Renderer 进程的 DOM;
二、webview
中存在一些 issues (1,2,3),这些问题我们不能解决,Electron 团队也不能解决——甚至,考虑到 webview
在 Chromuim 中狭窄的应用范围,可能 Chromuim 团队也没打算解决。
针对以上问题,我们决定使用browserview 来代替 webview。
browserview
和 webview
的区别
最大的区别在于 browserview
托管于 main process 而不是 renderer。这非常类似于 Chrome 中对页面的处理方式,因此可以获得很高的页面响应速度。
当然,因为从此 GUI 分属于两个 process,所以代价是我们必须在处理 GUI 布局时对 browserview
单独处理。
browserview
存在的问题
在使用中,我们发现 browserview
存在的问题主要表现在两方面。
-
browserview
缺少webview
丰富的 API。使用browserview
,你将无法使用插件,预加载脚本,截图等能力 -
browserview
不活动在 renderer 进程,因此无法使用舒服的 CSS 来控制布局。
对于第一点,我们在实现中选择直接操作 webContents
,来获取失去的方法和属性。对于第二点,我们设计了专门的 browserview manager
来控制 browserview
的布局外在表现。
使用 browserview
考虑到 browserview
的独立性,我们设计了一个 browserview manager 来管理所有 browserviews
,并使用 ipcMain 和 ipcRenderer 建立通讯。
当用户在客户端进行操作(如前进、后退、刷新、切换页等)时,对应的指令通过 Electron event 机制传达到 browserview manager,然后让 browserview manager
操作 browserview
和其中的 webcontents
执行指令。
结语
虽然 browserview
在 Electron 中依然是一个实验性功能,API 也不完备,缺乏 script preload 等 webview
拥有的机制。但如果你需要在 App 中嵌入外部网页,在合适的 trade-off 下,使用 browserview
不失一个好选择。
招聘时间~
FoxOne 是一个技术导向的创新团队。我们正在围绕基础研究和产品化,寻觅正确的区块链技术应用方向。而现在,改变世界需要有你同行。
我们正在招聘前端工程师、移动端工程师、爬虫工程师、Golang 研发工程师、社群产品运营。欢迎青睐 FoxOne 的优秀人才加入我们。
请留意我们的招聘邮箱为 jobs@fox.one
。谢谢大家阅读。