目前移動端越多越多的網頁開始H5化,一方面可以減少安裝包體積,另一方面也友善營運。但是相對于原生界面而言,H5的慢速問題一定被大家所诟病,針對這個問題,目前手Q存在幾種方案,最常見的便是離線包方案,但離線包存在幾個問題:
滞後性,内容顯示不及時;
覆寫率,很難達到100%;
校驗耗時,由于離線包的素材較多,加載時安全性校驗非常多;
除了上面的缺陷外,對于一些UGC架構的業務,離線包的支援也不是特别好。針對這些問題,業界存在一種基于TCP長連接配接的新方案(WebSo),專注于提高首屏的加載速度。WebSo的思路來源主要是由于android端在初始化webview和http拉取資源串行執行時都很耗時,如下圖:
WebSo基于這一前提,把串行變并行,并利用tcp長連接配接替換掉http,另外一個突破是針對html内容的動态性,增加了模闆和資料分離,變化頻率較多的資料定義為data,變化頻率較少的定義為template,基本實作流程如下圖:
手機QQ針對個别頁面最開始采用的也是WebSo這種方案,不過在灰階過程中發現資料不理想,尤其是首次加載及模闆變更時資料非常糟糕,仔細分析發現主要的原因包括下面幾點:
tcp長連接配接信令拉取資源時要經曆跨程序、伺服器中轉、信令排隊、加解密,導緻時間過長;
tcp長連接配接信令需要下載下傳完整個html才能塞給核心渲染,不能利用核心的邊下載下傳變渲染;
資料、模闆變更時會引起整個頁面重刷,導緻體驗很差。
異常時url不會智能切換
針對這幾點問題,為了讓使用者的體驗達到更好,增值産品部提出了sonic方案,第二部分我們來介紹一下具體的sonic實作細節。
我們從兩個場景來介紹具體實作。
第一種場景是使用者首次或者緩存失效時加載頁面,與WebSo一樣,sonic在初始化webview的同時也會并行發起http連接配接,在webview初始化好之後會在核心與http流之間建立橋接,橋接流在不同機型不同網速情況下可能有三種不同狀态:全記憶體流、記憶體流+網絡流、網絡流。在橋接流關閉時,我們會在終端根據模闆資料拆分規則對html進行内容分割,并記錄模闆和資料的tags資訊,利用這些tags資訊,可以在下次與伺服器通信時進行資料校驗和更新。具體實作思路如下:
第二種場景是使用者二次進入頁面,通過手Q灰階測試的觀察這種場景的占比較高,普遍情況下會在七成以上。這種場景我們會優先加載緩存,并且根據http(s)傳回碼的同步狀态,進行不同的處理。sonic首先會根據cacheoffline做不同的智能開關處理;然後根據本地的緩存狀态做不同的狀态轉換:如果完全命中緩存,則不作任何處理;如果發生模闆變更,處理邏輯會有點複雜,sonic會根據不同機型和網絡環境做智能切換處理,速度較快時會拉取完html流交給核心渲染,速度不快時仍然會建立橋接流,并且會對内容進行拆分;如果發生資料變更,sonic會對資料進行diff處理,和頁面通過js進行通信進行重新整理,這樣做的好處一方面可以不影響使用者的體驗,另一方面速度也更快。具體實作思路如下:
為了達到更好的效果,後續我們可能還會加入dns的優化,這樣做的好處是減少域名劫持,不過目前的方案已經能達到非常不錯的效果了。
下面我們分别針對vip中心首頁在四個場景的實驗資料來進行對比(android端外網灰階資料基本一緻,ios速度很快暫時沒有采用此方案),圖中每行的意義如下:
webviewStart-clickStart:點選url到activity的oncreate首行時間;
loadUrl-clickStart:點選url到loadurl的時間;
head-clickStart:點選url到頁面首行的執行時間;
domready-clickStart:點選url到dom準備好的時間;
active-clickStart:點選url到頁面互動的時間。
其中active-clickStart一般用來衡量頁面加載時的總時間。
第一種場景是首次啟動web程序、無緩存時的資料,可以發現首次啟動sonic比WebSo加載耗時減少53%:
第二種場景是非首次啟動web程序、模闆更新時的資料,可以發現sonic比WebSo減少22%:
第三種場景是非首次啟動web程序、模闆不變資料更新的資料,sonic比WebSo減少60%:
第四種場景是非首次啟動web程序、完全命中緩存的資料,sonic和WebSo的資料差不太多:
從實驗和手Q灰階的情況看,整體而言,sonic在絕大部分場景下已經能夠達到非常好的體驗,後續我們也會繼續進行進一步的優化,争取達到更好的體驗效果。
相關推薦