<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>

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

          共 4379字,需瀏覽 9分鐘

           ·

          2020-09-11 04:49


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

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

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

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

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

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

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

          3. 目標(biāo)

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

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

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

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

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

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

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

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

          (2)W3C Performance Timing

          與客戶端回調(diào)相比,W3C Performance Timing 提供了更細(xì)致的加載過程信息,但是不包含 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)時機(jī)不夠完整或過于“苛刻”,測不準(zhǔn)“頁面內(nèi)容可消費”的時間點
          通過追溯客戶端 onPageFinished 的回調(diào)時機(jī),發(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)確的頁面加載完成時機(jī)來自前端
          • 最準(zhǔn)確的 WebView 初始化時機(jī)來自客戶端
          因此,完善的耗時測量需由客戶端和前端協(xié)同完成。

          (1)前端側(cè)

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

          (2)客戶端側(cè)

          作為一個補(bǔ)充方案,客戶端可以通過 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 負(fù)責(zé)維護(hù) 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 頁面加載過程中的生效時機(jī)如下:

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

          (1)WebView 初始化

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

          (2)客戶端自建緩存

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

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

          在完成公共資源池開發(fā)后,頁面打開耗時出現(xiàn)了負(fù)優(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. 擴(kuò)展生命周期

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

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

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

          五、總結(jié)與展望

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

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

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

          ??愛心三連擊

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

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

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


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

          瀏覽 76
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

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

          手機(jī)掃一掃分享

          分享
          舉報
          <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>
                  草草影院国产第一页 | 香蕉久久国产AV一区二区 | 亚洲性爱电影网站 | 五月丁香导航 | 国产极品久久久久久久久久 |