提速30%:FoxOne 使用 Electron browserview 实践

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