提速30%:FoxOne 使用 Electron browserview 實踐
在 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 。謝謝大家閱讀。
來自:https://segmentfault.com/a/1190000014287834