1. QQ音樂客戶端Web頁面通用性能優(yōu)化實踐

        共 4379字,需瀏覽 9分鐘

         ·

        2020-09-11 04:49


        導(dǎo)語 | QQ音樂 Android 客戶端的 Web 頁面日均 PV 達到千萬量級,然而頁面的打開耗時與 Native 頁面相距甚遠,需要系統(tǒng)性優(yōu)化。本文將介紹 QQ 音樂 Android 客戶端在進行 Web 頁面通用性能優(yōu)化過程中的問題、思路、方案和效果,并嘗試對跨端場景的常見瓶頸和對策進行歸納。文章作者:關(guān)岳,QQ音樂客戶端開發(fā)工程師。

        一、問題與目標(biāo)

        作為一款注重于內(nèi)容運營的應(yīng)用程序,QQ 音樂 Android 客戶端的 Web 頁面日均 PV 達到千萬量級,評論頁、MV 頁等核心頁面均有 Web 頁面參與,或完全由 Web 實現(xiàn)。
        客戶端內(nèi) Web 頁面的打開耗時與 Native 頁面相距甚遠,需要系統(tǒng)性優(yōu)化。然而,現(xiàn)有的前端和跨端優(yōu)化方案,存在一定局限性。

        1. 前端優(yōu)化的局限

        針對 Web 頁面的耗時優(yōu)化,在優(yōu)化思路、方案、服務(wù)、工具鏈等方面都已經(jīng)建設(shè)得非常詳細。然而,在客戶端內(nèi) Web 頁面這一場景,純前端優(yōu)化存在以下兩個局限:
        • 無法規(guī)避 WebView 初始化耗時
        • 受限于 WebView 生命周期范圍
        從客戶端角度,除了思考優(yōu)化 WebView 初始化耗時之外,還可以從 “擴展前端生命周期” 的角度出發(fā),思考優(yōu)化方案。

        2. 跨端優(yōu)化的局限

        現(xiàn)有跨端優(yōu)化方案,包括離線包、VasSonic 等,為了達到最好的優(yōu)化效果,均需要前端終端共同參與改造。這導(dǎo)致存量頁面的邏輯改造增加,對線上頁面不夠友好,引入額外的成本和風(fēng)險。在前端開發(fā)資源不足時,這些優(yōu)化的開展存在一定難度。
        從減少前端開發(fā)工作量的角度來看,需要思考更具通用性、前端感知更小的優(yōu)化方案。

        3. 目標(biāo)

        基于本次優(yōu)化的背景,本次優(yōu)化提出以下兩方面的目標(biāo):增強通用性、減少前端改造成本。

        二、指標(biāo)設(shè)計

        在展開優(yōu)化思路和實施的同時,需要建立衡量優(yōu)化效果的性能指標(biāo)。

        1. 客戶端現(xiàn)有性能指標(biāo)數(shù)據(jù)

        接下來基于客戶端內(nèi) Web 頁面加載過程,描述客戶端現(xiàn)有性能指標(biāo)代表的時機。

        (1)客戶端 WebView 回調(diào)

        基于 Android WebView 的過程監(jiān)控回調(diào)和頁面框架能力,可以實現(xiàn)的性能監(jiān)控包括:

        其中,onMainFrameFinished?取第一個非主請求 (HTML) 的資源被攔截的時機。對于絕大多數(shù)頁面來說,此時已經(jīng)完成主請求 (HTML) 的下載,并已經(jīng)開始解析;可以粗略代表主請求流程結(jié)束。

        (2)W3C Performance Timing

        與客戶端回調(diào)相比,W3C Performance Timing 提供了更細致的加載過程信息,但是不包含 WebView 開始初始化的時間點。下圖中僅列出部分:

        2. 各端單獨采集的局限

        (1)前端采集的局限

        • 無法獨立獲取 WebView 開始初始化的時間點。
        • 想獲取最精確的加載完成時間點,主要依賴手動埋點。

        (2)客戶端采集的局限

        SSR (服務(wù)端渲染) 和 CSR (客戶端渲染),頁面內(nèi)容可消費的時間點不一致。
        對 WebView 頁面加載周期來說:
        • CSR 頁面需在前端頁面框架加載后再展示數(shù)據(jù),內(nèi)容請求完成并上屏,發(fā)生在頁面加載完成之后
        • SSR 頁面的首次內(nèi)容上屏可攜帶首屏數(shù)據(jù),因此在頁面加載完成之前,頁面內(nèi)容已經(jīng)可以被消費
        客戶端回調(diào)時機不夠完整或過于“苛刻”,測不準(zhǔn)“頁面內(nèi)容可消費”的時間點。
        通過追溯客戶端 onPageFinished 的回調(diào)時機,發(fā)現(xiàn)對應(yīng)的 Blink 代碼要求必須滿足:頁面解析完畢、 沒有正在下載的資源等條件。
        按照這個標(biāo)準(zhǔn),一旦存在某個圖片一直處在加載中,但頁面框架的其他內(nèi)容均已處理完畢,onPageFinished 回調(diào)也會等待圖片加載完成才回調(diào),與實際上的 “頁面內(nèi)容可消費” 時間點存在差異。

        3. 指標(biāo)設(shè)計方案

        結(jié)合上述分析,可以確定:
        • 最準(zhǔn)確的頁面加載完成時機來自前端
        • 最準(zhǔn)確的 WebView 初始化時機來自客戶端
        因此,完善的耗時測量需由客戶端和前端協(xié)同完成。

        (1)前端側(cè)

        前端自行完成結(jié)束時間點的設(shè)置,并從客戶端獲取 WebView 初始化時間點,統(tǒng)計上報打開耗時。
        • 前端通過手動埋點或監(jiān)聽 DOM 節(jié)點數(shù)變更,獲取加載完成時間點。
        • 前端統(tǒng)計時調(diào)用客戶端提供 JSAPI,獲取以 WebView 初始化時間點作為起點的耗時。
        • 并由前端完成加載耗時的計算和統(tǒng)計上報。

        (2)客戶端側(cè)

        作為一個補充方案,客戶端可以通過 JavaScript 注入獲取上述 W3C Performance Timing 中的?domInteractive?時間點,作為結(jié)束時間點。
        • 前端?domInteractive?時,已完成所有頁面展示必需資源的請求和處理
        • 耗時的差異,可以體現(xiàn)任何頁面的客戶端通用優(yōu)化效果
        • 可以衡量SSR(服務(wù)端渲染) 頁面的可消費耗時,和CSR(客戶端渲染)頁面的首幀耗時

        webView.evaluateJavascript( script?=?“(function(){return?performance.timing.domInteractive;})();”, ?callback?=?{?value?->?????responseEndDuration?=?value.toLong()?-?getOnCreateTimestamp()?}?)
        雖然 WebKit 負責(zé)維護 Performance Timing 的值,但是 WebView 并未提供接口獲取上述時間點的值。

        三、優(yōu)化方案和效果

        1. 優(yōu)化方案概述

        基于客戶端內(nèi) Web 頁面的加載流程,從 “WebView 初始化耗時優(yōu)化”、“資源加載耗時優(yōu)化”、“邏輯處理耗時優(yōu)化” 三個方面,提出了 5 個優(yōu)化項。
        • TBS (X5 內(nèi)核) 環(huán)境預(yù)加載
        • WebView 實例池
        • 主請求并行加載
        • Web 公共資源池
        • 跟膚邏輯優(yōu)化
        各優(yōu)化項在 Web 頁面加載過程中的生效時機如下:

        2. 優(yōu)化手段說明

        (1)WebView 初始化

        經(jīng)過前期分析,WebView 初始化耗時本身的耗時壓縮空間比較有限。因此優(yōu)化手段主要以初始化邏輯前置為主。例如,“WebView 實例池” 通過在應(yīng)用位于后臺、主線程卡頓影響不明顯的時機進行 WebView 預(yù)初始化,置換啟動 Web 頁面時的初始化耗時。

        (2)客戶端自建緩存

        為了實現(xiàn)前述各項資源加載優(yōu)化,客戶端需要獨立于 WebView 的緩存機制,自建一個資源緩存。
        自建緩存參考客戶端常用的三級緩存機制,基于 WebView 的強生命周期,設(shè)計了 “冷-熱緩存循環(huán)” 的緩存生命周期。
        例如,在 WebView 初始化的同時,自建緩存把頁面需要的資源從文件系統(tǒng)加載到內(nèi)存;向 WebView 資源攔截回調(diào)輸入字節(jié)流時,自建緩存一定從內(nèi)存緩存中輸出,輸出完畢后即可立即從內(nèi)存緩存中被清除。這一機制可以使內(nèi)存緩存的淘汰更積極,字節(jié)流在內(nèi)存中停留的時間更短,減少內(nèi)存占用。

        (3)公共資源內(nèi)聯(lián)

        在完成公共資源池開發(fā)后,頁面打開耗時出現(xiàn)了負優(yōu)化的情況。經(jīng)過分析,確定與資源攔截回調(diào)的性能瓶頸有關(guān)。
        • 單線程模型導(dǎo)致讀寫性能下降
        • 被攔截資源的數(shù)量越多,對性能的影響越容易被放大
        因此,為了減少資源攔截回調(diào)的性能影響,從減少攔截次數(shù)的角度,引入了公共資源內(nèi)聯(lián)優(yōu)化。
        • 公共資源加載到熱緩存后,轉(zhuǎn)換為對應(yīng)的 HTML 節(jié)點
        • 主請求并行加載完成后,直接在主請求字節(jié)流中替換其對應(yīng)的外聯(lián)節(jié)點;替換后的新字節(jié)流返回 WebView
        引入公共資源內(nèi)聯(lián)后,基本抵消了資源攔截回調(diào)的性能影響,頁面加載耗時提升 3.2%。

        3. 優(yōu)化效果

        QQ 音樂 Android 端內(nèi)評論頁:
        • 加載耗時降低 26.2% (1932ms → 1426ms)
        • 跳出率降低?
        • 停留時長中位數(shù)增加

        四、跨端場景的瓶頸與對策

        基于在 WebView 場景下的優(yōu)化過程,推及跨端場景可能存在的類似問題,本文嘗試給出一些跨端場景中可能的性能瓶頸及應(yīng)對方式。

        1. 前終端通信通道效能不足,考慮 “少次多量”

        跨平臺方案 (WebView、React Native 等) 普遍存在前終端通信通道效能不足的問題。
        • WebView 通道不支持較大量級數(shù)據(jù)的傳遞
        • 通信線程多為單線程,甚至需要在主線程發(fā)起或處理通信
        • 對傳遞次數(shù)的敏感程度大于對傳遞數(shù)據(jù)總量的敏感程度
        因此,當(dāng)在跨端場景出現(xiàn)大數(shù)據(jù)量傳遞時,需要優(yōu)先考慮當(dāng)前通信通道的可用性。在需要傳遞數(shù)據(jù)總量無法壓縮的情況下,如果通道允許,盡量減少傳遞次數(shù),增加單次傳遞的數(shù)據(jù)量。
        “公共資源內(nèi)聯(lián)” 即是這一思路的實踐。

        2. 擴展生命周期

        前端生命周期有限??蛻舳丝梢岳迷谇岸松芷谝酝獾臅r間,進行適當(dāng)?shù)馁Y源前置和邏輯前置,降低頁面加載耗時。
        例如上述優(yōu)化中的 “公共資源池”、“主請求并行加載” 等,體現(xiàn)了擴展生命周期的思想。除此之外,微信小程序的雙線程模型[1]通過引入 JSCore,增加前端代碼的可執(zhí)行時長,并通過離線包等手段幫助前端擴展生命周期。

        3. 精簡 / 前置公共庫代碼

        如果前端頁面共用公共庫,隨著前端業(yè)務(wù)的復(fù)雜化,公共庫的自然膨脹,可能會放大腳本解析與執(zhí)行的耗時。
        針對 Web 頁面,可以通過精簡基礎(chǔ)庫的方式,減少無關(guān)代碼的執(zhí)行;針對 React Native 頁面,可以通過進行分包和實例預(yù)加載,讓更多基礎(chǔ)庫代碼在頁面加載前執(zhí)行,從而降低頁面啟動時執(zhí)行的代碼量,減少耗時。

        五、總結(jié)與展望

        本文基于客戶端內(nèi) Web 頁面的加載特點,針對 WebView 初始化、資源加載和邏輯處理現(xiàn)狀中的問題和瓶頸,設(shè)計并實施了 5 個優(yōu)化項,優(yōu)化效果比較明顯。并且嘗試對跨端場景的瓶頸與對策進行歸納,嘗試為后續(xù)跨端場景的優(yōu)化工作提供思路。
        未來,團隊還將進一步豐富客戶端與前端的協(xié)同性能監(jiān)控,并允許前端通過更精細化的方式啟動客戶端 Web 頁面框架。遠期,還將嘗試探索 CGI 前置、引入 JSCore 等手段,進一步提升特定場景下的 Web 頁面加載耗時。
        參考資料:

        [1] 微信小程序的雙線程模型:

        https://developers.weixin.qq.com/ebook?action=get_post_info&docid=0000286f908988db00866b85f5640a

        ??愛心三連擊

        1.看到這里了就點個在看支持下吧,你的在看是我創(chuàng)作的動力。

        2.關(guān)注公眾號程序員成長指北,回復(fù)「1」加入Node進階交流群!「在這里有好多 Node 開發(fā)者,會討論 Node 知識,互相學(xué)習(xí)」!

        3.也可添加微信【ikoala520】,一起成長。


        “在看轉(zhuǎn)發(fā)”是最大的支持

        瀏覽 76
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

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

        手機掃一掃分享

        分享
        舉報
          
          

            1. 麻豆91蜜桃传媒在线观看 | 成人一级黄色毛片 | 操小嫩逼视频 | AAA级片 | 国产视频97 |