<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Zey-如何借助客戶端能力優(yōu)化 H5 啟動速度

          共 3281字,需瀏覽 7分鐘

           ·

          2021-06-28 01:35

          前端早早聊大會,前端成長的新起點,與掘金聯(lián)合舉辦。加微信 codingdreamer 進大會專屬周邊群,贏在新的起跑線。


          第二十八屆|前端 WebGL專場,了解3D/可視化/渲染管線/動畫等等的可能性,6-26 全天直播,9 位講師(貝殼/阿里云/螞蟻/奇安信/小米/UC/美團等等),點我上車?? (報名地址):

          所有往期都有全程錄播,可以購買年票一次性解鎖全部

          ??更多活動



          正文如下

          本文是第十八屆 - 前端早早聊性能優(yōu)化專場,也是早早聊第 125 場,來自 騰訊-Zey 的分享。

          Hybird Web 頁面的性能問題一直都非常困擾開發(fā)者,本文講述如何從客戶端角度優(yōu)化 App 內(nèi)的 H5 頁面啟動性能。介紹一些常見的方法,供大家參考,希望可以有幫助。

          從客戶端角度的優(yōu)化思路

          可以先看下大致的啟動流程,如下圖,整個過程基本是串行的,HTML 需要在 Webview 加載完加載,JS 需要根據(jù)HTML 的內(nèi)容加載,首屏數(shù)據(jù)也需要執(zhí)行 JS 之后再請求。但是如果我們可以利用客戶端的能力,可以讓一些耗時的過程并行起來,這樣可以節(jié)省用戶等待的時間。

          比如,說這里 WebView 的啟動和 HTML 的下載都需要時間,但是像 WebView 啟動的時候,其實并沒有占用任何網(wǎng)絡的資源,這時候網(wǎng)絡是空閑的。那么,如果能夠并行的去請求首屏需要的數(shù)據(jù),那么我們就能夠在 JS 加載完成之后,立刻拿到首屏的數(shù)據(jù),從而提高用戶首屏的速度。

          同時,對于客戶端而言,它還可以做一些資源的緩存,比如 HTML 下載和 JS 下載,這些資源如果我們下載過一次之后就把它存儲在客戶端。那么,等下次加載的時候,其實就不用重新下載。

          有了緩存能力,那么我們其實也可以有預加載資源的能力。當還沒有打開頁面的時候,提前預加載一些資源。減少頁面打開耗時。

          所以,總結來說,就是利用客戶端的能力來實現(xiàn)并行、預加載、緩存等功能,減少 H5 啟動流程中的耗時階段。

          并行接口請求

          如前面所說,H5 加載是一個串行的過程。我們利用客戶端能力去異步請求首屏數(shù)據(jù),然后再把首屏數(shù)據(jù)交給 H5,實現(xiàn)并行請求。

          整個流程可以由一個 JsBridge 完成 getPreloadedData(callback)。

          啟動時,客戶端并行執(zhí)行。H5 啟動和首屏數(shù)據(jù)請求。這里首屏數(shù)據(jù)的接口信息,可以通過一些配置關聯(lián)起來。比如頁面 URL 里或者一個單獨的配置文件。

          對客戶端而言,H5 初始化的時間和數(shù)據(jù)請求的時間先后不確定。所以,如果客戶端先拿到數(shù)據(jù),會把數(shù)據(jù)緩存在內(nèi)存里,等待 H5 來調(diào)用 JsBridge。如果 H5 先來詢問數(shù)據(jù),客戶端會把 H5 的 callback 緩存下來,等數(shù)據(jù)獲取之后再回調(diào)。

          在 H5 啟動中,不但會調(diào)用上面的 JsBridge 向客戶端要數(shù)據(jù),同時也會自己發(fā)起首屏請求,所以這里需要有個競速邏輯,使用最先返回的數(shù)據(jù)渲染。

          WebView 容器化

          我們都知道如果頁面有預加載渲染,用戶打開時,頁面速度就會很快展示,對于體驗提升非常明顯。但是,我們要慎用預加載:

          1. 預加載會占用更多內(nèi)存,消耗更多流量;
          2. 預加載可能搶占客戶端資源,導致用戶當前的頁面卡頓;
          3. 不可能所有頁面都預加載,未預加載的頁面還是很慢;

          所以,我們在思考,是否有一種方式,只預加載公共的部分,業(yè)務的部分等打開頁面的時候再去加載,這樣對于頁面的性能也會有提升,同時,也會減少預加載帶來的副作用。

          所以,我們提出了一個 WebView 容器化的方案。

          只預加載公共的部分,減少因為這部分導致的耗時,比如:WebView 初始化時間、框架庫加載時間等。如果業(yè)務頁面之間相似度高,還可以有更深層的定制。

          客戶端會預創(chuàng)建緩存一個 WebView 容器,供使用。當加載一個頁面后,會消耗一個容器,客戶端會延遲2s再創(chuàng)建一個。

          如下是,WebView 容器化需要的能力,總體來說是,需要一個容器頁面項目和業(yè)務項目。容器需要有一些通用的能力,核心是能夠動態(tài)加載js然后執(zhí)行渲染邏輯。業(yè)務項目,比普通的項目需要多一個編譯入口,讓頁面能夠編譯成一個單獨的js,并把組件暴露出來渲染。比如,Webpack 的 UMD 導出方式:文檔鏈接

          加載時,客戶端主要工作就是從預加載的 WebView 池中取出一個可以用的 WebView,然后執(zhí)行 JsBridge,通知對應的 JS 地址。這里可以有多種實現(xiàn)方式,比如傳業(yè)務 JS 鏈接過去,然后 Web 代碼請求 JS 內(nèi)容。也可以客戶端直接把 JS 的內(nèi)容提前下載下來,直接把內(nèi)容給 WebView。可以更快完成加載。

          上圖的 JS 偽代碼是以動態(tài)加載 JS 鏈接為例。

          WebView 容器化結合 SSR

          當頁面變成 SSR 直出場景,會有什么不同嗎?

          首先,客戶端加載的內(nèi)容不同。普通頁面加載的內(nèi)容是靜態(tài)資源,不包含數(shù)據(jù)。而 SSR 里不但有數(shù)據(jù),還有預渲染的 DOM 節(jié)點。

          但是,在 SSR 場景下把用戶的 HTML 緩存下來會有什么問題嗎?比如,我們這樣來做優(yōu)化:每次把用戶的 HTML緩存下來,等用戶下載打開頁面的時候,直接加載上次緩存的 HTML 內(nèi)容,加快首屏速度。

          因為直出的 HTML 中包含了用戶的首屏數(shù)據(jù)和 DOM,所以,直接加載上次的 HTML 內(nèi)容,會包含上次頁面的數(shù)據(jù),大概率和當前的數(shù)據(jù)不一樣。就是說,每次用戶打開頁面的時候,都還需要請求一次新的直出 HTML,再觸發(fā)頁面整體重新渲染(類似頁面 reload ),才能看到正確的數(shù)據(jù)。

          這里有個優(yōu)化的方式,就是把 HTML 拆分得細一點。分為數(shù)據(jù)和模板兩部分。數(shù)據(jù)是每次變化的部分,而模板是不常變的,以此來減少頁面的整體重新渲染。

          模板和數(shù)據(jù)的拆分邏輯,可以參考: 開源庫VasSonic

          那么,分得細了之后,緩存命中情況也會復雜一些:

          接下來,通過不同的緩存命中情況流程圖,來詳細分析:

          首次加載本地沒有緩存,需要全量從服務端拉取,加載后把下載的 HTML 分模塊和數(shù)據(jù)緩存起來。

          完全命中緩存的情況,因為沒有任何變化,加載緩存即可。這里比對的是兩個 hash,HTML 的 hash 和模板的hash,就是先判斷整體內(nèi)容有沒有變化,沒有變化就304。

          僅數(shù)據(jù)變化的情況,就是 HTML 的 hash 發(fā)生了變化,然后對比模板的 hash,發(fā)現(xiàn)是一樣的,就只需要返回數(shù)據(jù)給客戶端。客戶端再把數(shù)據(jù)透傳給 H5,H5 通過修改業(yè)務數(shù)據(jù),實現(xiàn)頁面更新。這種只 JS 層面的數(shù)據(jù)變化,對頁面的變化影響比較小,用戶感知不明顯。

          未命中緩存的情況,就是 HTML 的 hash 和模板的 hash 都發(fā)生了變化。這是服務器會返回完整的 HTML 內(nèi)容,客戶端通過重新加載 HTML 來實現(xiàn)頁面的更新。

          整體流程圖如上,主要增加了降級邏輯,在沒有預加載 WebView 的降級情況下,客戶端拉取數(shù)據(jù)會和 WebView 并行。

          總結

          主要講了三種優(yōu)化手段:1、首屏數(shù)據(jù)并行加載,WebView 初始化資源下載 與 首屏數(shù)據(jù)請求并行,縮短用戶等待時間;2、WebView 容器化,預加載通用的 WebView,減少資源占用,同時達到預加載的目的;3、WebView 容器化+ SSR,結合 SSR 場景和緩存邏輯,實現(xiàn)更快的首屏速度。

          當然,還有其他的一些優(yōu)化手段,比如 React Native、PWA 等,也對首屏優(yōu)化非常明顯。歡迎有興趣的同學一起交流學習。


          別忘了 6-26(本周六) 的第二十八屆|前端 WebGL專場,了解3D/可視化/渲染管線/動畫等等的可能性,6-26 全天直播,9 位講師(貝殼/阿里云/螞蟻/奇安信/小米/UC/美團等等),點我上車?? (報名地址):

          所有往期都有全程錄播,可以購買年票一次性解鎖全部

          ??更多活動


          別忘了給文章點贊


          瀏覽 76
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  色高清国产在线观看 | 99久热在线精品视频 | 韩国精品无码一区二区 | 手机毛片 | 一级A一级闪射免费播放 |