H5秒開方案大全

老闆說 , 頁面打開速度過慢? 頁面加載性能不達標? 下面我們來看下各個大廠和團隊的秒開經典方案,有沒有一款適合你去探索?

本頁面會列舉和總結偏向與客戶端結合的 hybrid 秒開方案,純前端方案也會部分提及。

常用的加速方法

說起 H5 性能優化方案,是個老生常談的話題,通常的 web 優化方法,基本圍繞在資源加載和 html 渲染兩個方面。前者針對首屏,後者針對可交互。資源優化上,我們總的方向是圍繞更小的資源包上,比如常見的:壓縮、減包、拆包、動態加載包及圖片優化上。html 渲染上總的方向是更快的展示內容,比如通過 CDN 分發、DNS 解析、http 緩存、數據預請求,數據緩存及首屏優化大殺器——直出等。

這些方案是各種前端面試中必考點,也是作為一個前端開發,當遇到性能問題、需要解決性能問題時的能夠想要最為首要,也基本的思路。而具體應該使用什麼樣的方案,取決於實際開發需求、優先級、綜合成本、及投入產出比等。

在 react-native、weex、及 flutter 等客戶端的技術不斷在衝擊傳統 hybrid 的時候,hybrid 也在一路演化、加速,朝著一個使其達到與原生相媲美的方向發展。下面歸納了 hybrid 發展中出現的一些方案,排序不分先後。

直出+離線包緩存

為了優化首屏,大部分主流的頁面會通過服務器進行渲染,吐出 html 文件到前端,解決轉菊花比較久的問題,不同類型的主流框架,都會有一套後臺渲染方案,比如 vue-server-renderer、react-dom/server 等。直出省去了前端渲染,及 ajax 請求的時間,雖然直出能夠通過各種緩存策略優化得很好,但是加載 html 然後需要時間。

通過離線包技術能夠很好解決 html 文件本身加載需要時間的問題。離線包基本思路都是通過 webview 統一攔截 url,將資源映射到本地離線包,更新的時候對版本資源檢測,下載和維護本地緩存目錄中的資源。比如騰訊的 webso 和 Alloykit 的離線包方案。

H5秒開方案大全

離線包策略在很多大廠運用比較成熟,它對 web 端而言,是相對透明,侵入性非常小。

客戶端代理的 VasSonic

在 hybrid h5 中,用戶從點擊到看見頁面之間,還存在 webview 初始化,請求資源的時間,而這裡的過程是串行的,對於追求更極致的體驗來說,這裡是有優化掉的空間和可能。

VasSonic 是騰訊增值會員團隊研發的一個輕量級 hybrid 框架,支持上面提到的離線包策略,更進一步的是,它還做了以下優化:

  • webview 初始化和通過客戶端代理資源請求並行-
  • 流式攔截請求,邊加載邊渲染
  • 實現了動態緩存和增量更新。

簡單說下它是怎麼做到的,客戶端代理資源請求並行沒什麼好說的,就是在創建 webview 之前,通過客戶端代理建立網絡連接,請求 html,然後緩存起來,等待 webview 線程發起 html 資源請求的時候,客戶端進行攔截,將緩存好的 html 返回給 webview。

動態緩存和增量更新如何做到呢?

VasSonic 將 html 的內容分為 html 模板和動態數據兩部分,如何區分這兩種類型呢,它自己定義了一套 html 註釋標記規則,通過標籤劃分哪些是動態數據,哪些是模板數據。然後再拓展了 http 頭部,定製了一套請求後臺的約定。webview 發起 http 請求時會將頁面內容的 id 攜帶過去,後臺處理判斷後,再告訴客戶端是否需要更新局部數據,如果是則將緩存的 html 模板與新數據拼接成新的 html,最後計算出數據差異部分,通過 js 回調給頁面,進行佈局刷新。

H5秒開方案大全

[圖來源網絡]

VasSonic 的方案整體思路和效果非常不錯,特別是對於大部分 web 場景,通常我們的模板較少發生變化,大部分是數據部分變化,能夠很好的通過局部刷新做到秒開效果。對於首次加載而言,通過併發請求和 webview 創建帶來了不錯的性能提升,還能無縫的支持離線包策略。

但是 VasSonic 定義了一套特殊的註釋標記及拓展了頭部,需要包括後臺在內的前後端進行改造,對 web 侵入性非常強,接入的工作量及維護成本會非常大。

PWA+直出+預加載

不管是離線包技術,還是 webview 代理請求,都是對前端侵入非常大的,PWA 作為 web 標準,能夠通過純 web 的方案去加速和優化加載性能。

首先,PWA 的能夠通過 cacheStorage 緩存普通的圖片、JS、CSS 資源。另一方面,在傳統的 http cache 中,我們一般不會緩存 HTML,這是因為頁面一旦設置了過長的 max-age,在瀏覽器緩存過期時間內,用戶看到的永遠將是舊的。

如果使用了 PWA 的 HTML 頁面,能否直接緩存呢?由於 PWA 可精細化控制緩存,答案是可以的。

對於直出 HTML,我們可以配合 PWA,將從後臺直出的文件,緩存到 cacheStorage,在下一次請求時,優先從本地緩存中獲取,同時發起網絡請求更新本地 html 文件。

但是在 hybrid 的 h5 應用,第一次啟動的加載資源仍然費時,我們可以通過 app 端上支持預加載一個 javascript 腳本,拉取需要 PWA 緩存的頁面,可以提前完成緩存。

對於非直出的頁面,我們仍然無法避免瀏覽器渲染 html 時間的問題,應該如何 kill 調這裡的時間呢?

這裡明確兩個點,第一次永遠只能靠提前加載,所以上面的藉助端上預加載腳本任然生效;第二點非直出頁面,每個頁面需要有獨一無二的標記,比如 hash。瀏覽器獲取到數據,並且渲染好的 html,能夠通過 outerHTML 方法,將 html 頁面緩存到 cacheStorage 中,第二次訪問任然優先從本地獲取,同時發起 html 請求,通過對比其中唯一標識的差異,決定是否需要更新。

H5秒開方案大全

PWA 一系列方案替代離線包策略,帶來的好處是,屬於 web 標準,適用於普通能夠支持 service-worker 的 H5 頁面。在允許兼容問題允許的情況下,建議主加。

NSR 渲染

GMTC2019 全球大前端技術上 UC 團隊提到了 0.3 秒的 “閃開” 方案。NSR 就是前端版本的 SSR,非常具有啟發性。

其核心思路是,藉助瀏覽器啟用一個 JS-Runtime,提前將下載好的 html 模板及預取的 feed 流數據進行渲染,然後將 HTML 設置到內存級別的 MemoryCache 中,從而達到點開即看的效果。

NSR 將 SSR 渲染的過程分發到了各個用戶的端中,在減少了後臺請求壓力的同時,也加進一步快了頁面打開速度,堪稱做到極致。

問題是數據預取和預渲染帶來額外的流量和性能開銷,特別是流量,如何更準確的預測用戶行為,提高命中率是非常重要的事。類似 NSR 的方案我們也在逐步探索中。

客戶端 PWA

在實際測試、及和瀏覽器團隊的同學瞭解和溝通中,service-worker 在 webview 實現性能並沒有想象中好。在某項目下掉 sw 後,整體大盤訪問速度整體反而提升上升了大概 300ms。

這對 hybrid 應用而言,就提出了一項新的思路和挑戰,能否在客戶上實現一套基本的 service-worker api?從而達到和 web 標準相兼容。這裡也只是一種思路和想法,有大量待探索的問題點,比如 webview sw 具體的性能現狀,未來的支持情況呢,自行實現的成本,及最終帶來的效果和價值等。

小程序化

小程序生態已經非常成熟了,各大廠也都已經推出了自己平臺的小程序,國內廠商也不斷在嘗試推進 MiniApp w3c 標準。不管從加載速度還是頁面流暢度小程序都要高於 H5 頁面,其原因是通過在架構上對開發進行規範化和約束化,小程序內部將 webview 渲染和 js 執行分離開來,然後通過離線包,頁面拆分,預加載頁面等一系列優化手段,讓小程序天然具備了大量的 H5 優化後的效果,其代價是犧牲了 web 的靈活性。但對於 hybrid 開發,通過原生客戶端底層支持這種小程序環境,然後大量業務邏輯採用小程序方案開發,來達到迭代速度與性能兼併的效果,是一種非常不錯的方向。

本文主要總結了這幾天大量閱讀梳理十幾篇關於秒開的文章和及最近的一些思考與實踐,從中提取出了部分具有代表性的方案。

不管哪種類型的方案,發現其總的思路和方向都是:

  • 在整個鏈路中減少中間環節。比如將串行改並行,包括小程序內部執行機制。
  • 儘可能的預加載、預執行。比如從數據預取,到頁面預取渲染等。

任何轉換都有代價,加速本質上就是在用更多的網絡、內存和 CPU 換取速度,以空間換時間。

原文:http://www.alloyteam.com/2019/10/h5-performance-optimize/


分享到:


相關文章: