天天看點

webview加載頁面有2秒白屏_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 的離線包方案。

webview加載頁面有2秒白屏_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 回調給頁面,進行布局重新整理。

webview加載頁面有2秒白屏_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 請求,通過對比其中唯一辨別的差異,決定是否需要更新。

webview加載頁面有2秒白屏_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 換取速度,以空間換時間。