Android使用H5容器加載速度優(yōu)化方案
作者:SEU_Calvin 地址: https://blog.csdn.net/SEU_Calvin/article/details/113809809?spm=1001.2014.3001.5502
1. 背景介紹
在偏重活動運營的電商App中,受制于App版本審核,具備開發(fā)周期短、可靈活發(fā)布等特點的H5頁面受到青睞,承載了很多重要業(yè)務(wù)。但App Webview存在令人煩惱的性能問題,特別突出的是加載速度慢,和Native頁面相比用戶體驗較差。因此本文將從H5加載速度優(yōu)化方面,總結(jié)了XCache、Prefetch、容器預(yù)熱三種優(yōu)化方案,以及上線后的提速效果分享。
2. XCache離線緩存提速方案
2.1 方案背景
為了有效解決 Android H5的性能問題,除了使用Android WebView自身的緩存機制,還可以自己針對某一需求場景構(gòu)建緩存機制。
通常來說,加載一個h5頁面最耗時的部分就在于頁面資源的下載,如html、css、js以及圖片文件,如果這些文件不需要下載,那么剩下的時間開銷基本就是業(yè)務(wù)數(shù)據(jù)的下載以及頁面的解析渲染了。
2.2 方案總體介紹

首先構(gòu)建Admin后臺管理系統(tǒng),主要幫助開發(fā)人員對H5資源進行配置管理,主要包括資源的版本管理、總?cè)萘抗芾硪约百Y源的發(fā)布。
XCache服務(wù)器負責(zé)提供資源的下載接口,CDN作為資源鏡像,在Server接口連續(xù)失敗后提供備用接口。
移動端在合適的時機拉取資源配置表,以及資源本身,并在WebView發(fā)起資源請求時,判斷是否命中資源緩存,從而提高加載速度(尤其是弱網(wǎng)環(huán)境),并節(jié)省流量。
在資源被訪問以及命中緩存后,將相關(guān)的數(shù)據(jù)進行上傳統(tǒng)計,從而協(xié)助發(fā)現(xiàn)問題、調(diào)整策略。
2.3 Android端具體方案介紹

資源配置表檢查更新接口的觸發(fā)時機:啟動/打開webview/切前臺/退出webview,配置表需要實時更新,但是如果連續(xù)觸發(fā),疲勞度控制在30s內(nèi)不重復(fù)觸發(fā)。
資源配置表接口的異常兜底機制:接口后端連續(xù)異常code 5次,使用的CDN上最新資源鏡像(APP內(nèi)置最新CDN鏡像鏈接)。
根據(jù)和上一次的資源配置表進行diff,獲取資源的"增、刪、更新"信息,其中,同樣的資源根據(jù)版本號進行更新。
資源的下載時機:當APP空閑時機,并且處于Wi-Fi環(huán)境,同時子線程隊列下載優(yōu)先級為最低,下載下來的資源需要進行MD5校驗防止惡意攻擊。
資源的更新機制: 針對資源Update的情況, 放開Wi-Fi限制, 以保證實時性. (只針對本地有該資源, 并且配置表告訴客戶端該資源需要更新的case. 如果只是單純的新增資源(本地沒有該資源), 還是要被4G環(huán)境限制, 防止新用戶第一次4G打開app就一股腦下載幾十M的資源, 從而被投訴)。
緩存策略:在移動端支持兩級緩存:內(nèi)存緩存、磁盤緩存,均以LRU作為緩存策略,內(nèi)存緩存的優(yōu)先級大于磁盤緩存。其中,內(nèi)存緩存容量大小設(shè)置為10M(內(nèi)存緊張釋放內(nèi)存緩存), 磁盤緩存容量大小設(shè)置為100M。
在H5頁面資源請求中,如果命中了配置表中的資源,則優(yōu)先尋找本地緩存,緩存命中則直接使用,若沒有發(fā)現(xiàn)本地緩存(原因有很多,比如非Wi-Fi環(huán)境下資源沒有被提前下載),則自行下載使用的同時,將資源放入內(nèi)存緩存以及磁盤緩存,方便第二次的緩存命中。
2.4 提速效果總結(jié)
2.4.1 白屏?xí)r間更短
以簽到頁為例, Android端頁面白屏100ms以內(nèi)的占比從原來的28.4%提升到了71.2%。
2.4.2 更為用戶省流量
每年XCache將為用戶節(jié)省的流量超過100TB。(PV * 緩存命中率 * 資源大小 = 省流)
2.4.3 留住了更多“沒有耐心”的用戶
以簽到頁為例, 每天因為不愿意等H5白屏而選擇退出的用戶至少減少了1200名。
3. Prefetch數(shù)據(jù)并行加載提速方案
3.1 方案背景
如果說XCache離線緩存提速方案解決的是H5資源文件下載慢的問題,那么Prefetch并行加載就是從數(shù)據(jù)的角度來進行的優(yōu)化。

以超級會員頁H5為例,整個H5的加載流程是串行的,業(yè)務(wù)接口必須在H5資源ready、以及js環(huán)境ready之后才會發(fā)出;
針對待優(yōu)化頁面,如果在H5頁面被打開的同時,客戶端協(xié)助H5提前將業(yè)務(wù)請求發(fā)出,并維護該數(shù)據(jù)在內(nèi)存中,并通過JsBridge將數(shù)據(jù)提供給H5,H5便不需要再發(fā)出請求,從而利用并行特性,縮短H5的白屏?xí)r間。
3.2 方案總體介紹

在客戶端首次打開H5頁面時,拉取prefetch配置文件,其中動態(tài)配置了待優(yōu)化頁面、協(xié)助客戶端完成url—>api。
考慮到H5頁面的業(yè)務(wù)請求不僅依賴于Native注入的Native Cookie,還依賴于H5的一些特有Cookie,因此客戶端在拉取配置表的同時,需要觸發(fā)一次H5 Cookie的請求,且該Cookie不會污染Native Cookie,僅用于Prefetch請求。
當客戶端攔截并感知到待優(yōu)化頁面被打開時,主動拉取H5側(cè)的業(yè)務(wù)數(shù)據(jù),用hash算法將數(shù)據(jù)存在內(nèi)存Map中,其中hash(url+api)作為key,并約定H5側(cè)通過jsbridge以及相同的key來獲取數(shù)據(jù)。該數(shù)據(jù)的生命周期很短,退出H5或者被H5側(cè)拿走即清空。
最后在H5側(cè)的相關(guān)頁面中,修改少量邏輯,在獲取業(yè)務(wù)數(shù)據(jù)的地方,優(yōu)先通過jsbridge向客戶端拉取業(yè)務(wù)數(shù)據(jù),如果拉取成功,便省去了自行請求的時間,從而達到優(yōu)化的目的。如果拉取失敗,則降級為自行請求的舊邏輯。
3.3 方案細節(jié)點
3.3.1 URL攔截規(guī)則優(yōu)化
如果URL匹配規(guī)則過于苛刻, 會導(dǎo)致一些情況下優(yōu)化命中失敗, 外部投放的case會在url后加參數(shù), 需要在攔截url時進行靈活的匹配Scheme、Host和Path, 和iOS端拉齊, 提高優(yōu)化命中率.
3.3.2 代理接口參數(shù)支持

3.3.3 配置表接口前置
prefetch接口的獲取時機需要保證在App之后, 用戶進入H5頁面之前, 建議在App空閑時進行.
3.3.4 配置表出錯兜底(防止爆內(nèi)存)
限制每個頁面的請求數(shù)量上限為3條
限制總的頁面數(shù)量上限為50條(平臺做限制&客戶端只取前50條)
3.4 業(yè)內(nèi)方案對比

由于業(yè)內(nèi)方案中,任何細節(jié)出錯(譬如Prefetch配置表拉取失敗、客戶端攔截過程出錯等等),都會導(dǎo)致H5側(cè)都無法獲取到數(shù)據(jù),從而導(dǎo)致白屏。
因此我們采用了更加安全、以及解耦的方案,H5僅在當前拉取一次客戶端數(shù)據(jù),并加入兜底機制,降低由于優(yōu)化導(dǎo)致的白屏情況,以及出現(xiàn)白屏不用花精力在“是不是因為Prefetch導(dǎo)致的”。而因為接口過于耗時導(dǎo)致優(yōu)化成功率降低到88%左右,也是完全可以接受的。
3.5 提速效果總結(jié)
3.5.1 輕量級
不需要預(yù)工作, 不拖慢App速度,因為Prefetch是在用戶點擊進入H5的那一刻才開始工作, 所以不會存在類似于XCache的預(yù)加載環(huán)節(jié)。
3.5.2 H5頁面呈現(xiàn)速度更快
為了排除其他業(yè)務(wù)對優(yōu)化效果量化的影響,Android端單獨上線Prefetch,同一時間iOS未上線Prefetch。
簽到頁H5的首屏完整呈現(xiàn)達標率均值提升6.3%, 對照組iOS降低6.7%;超會頁H5的首屏完整呈現(xiàn)達標率均值提升4.1%, 對照組iOS降低2.4%
4. 容器預(yù)熱提速方案
4.1 方案背景
當App首次打開時,默認是并不初始化瀏覽器內(nèi)核的;只有當創(chuàng)建WebView實例的時候,才會創(chuàng)建WebView的基礎(chǔ)框架,所以啟動瀏覽器內(nèi)核的開銷都算到了用戶首次打開H5頁面里。WebView首次初始化后,一些WebView共用的全局服務(wù)或資源對象仍沒有釋放,因此第二次打開H5頁面會變快。

經(jīng)過測試,第二次H5的打開速度比首次打開要快32.8%。
4.2 方案總體介紹

我們可以在App啟動之后,并且空閑時,預(yù)先將容器WebView進行一次初始化, 當?shù)诙纬跏蓟疻ebView的時候速度就快多了, 或者直接將其拿來使用。
同時,我們針對“不愛打開H5”的用戶,有選擇性的進行容器預(yù)熱,從而盡量避免額外的內(nèi)存開銷。
4.3 提速效果總結(jié)
由于方案未上線,預(yù)計將為用戶減少20%以上的首次H5打開時間。
5. 文章總結(jié)
相對于React Ntive、Flutter等跨端方案,H5開發(fā)有著更加靈活的便利性,因此總能在移動互聯(lián)網(wǎng)的浪潮中占據(jù)一席之地。本文從資源緩存、數(shù)據(jù)并行加載、容器預(yù)熱三個方面對H5進行了加載速度優(yōu)化,都有比較好的提速效果,提升了用戶的使用體驗。
