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

          騰訊音樂(lè)移動(dòng)端頁(yè)面通用性能優(yōu)化實(shí)踐

          共 4235字,需瀏覽 9分鐘

           ·

          2020-09-12 08:18

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

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

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

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

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

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

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

          3. 目標(biāo)

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

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

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

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

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

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

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

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

          (2)W3C Performance Timing

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

          2. 各端單獨(dú)采集的局限

          (1)前端采集的局限

          • 無(wú)法獨(dú)立獲取 WebView 開(kāi)始初始化的時(shí)間點(diǎn)。
          • 想獲取最精確的加載完成時(shí)間點(diǎn),主要依賴(lài)手動(dòng)埋點(diǎn)。

          (2)客戶(hù)端采集的局限

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

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

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

          (1)前端側(cè)

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

          (2)客戶(hù)端側(cè)

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

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

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

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

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

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

          (1)WebView 初始化

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

          (2)客戶(hù)端自建緩存

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

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

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

          3. 優(yōu)化效果

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

          四、跨端場(chǎng)景的瓶頸與對(duì)策

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

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

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

          2. 擴(kuò)展生命周期

          前端生命周期有限。客戶(hù)端可以利用在前端生命周期以外的時(shí)間,進(jìn)行適當(dāng)?shù)馁Y源前置和邏輯前置,降低頁(yè)面加載耗時(shí)。
          例如上述優(yōu)化中的 “公共資源池”、“主請(qǐng)求并行加載” 等,體現(xiàn)了擴(kuò)展生命周期的思想。除此之外,微信小程序的雙線(xiàn)程模型[1]通過(guò)引入 JSCore,增加前端代碼的可執(zhí)行時(shí)長(zhǎng),并通過(guò)離線(xiàn)包等手段幫助前端擴(kuò)展生命周期。

          3. 精簡(jiǎn) / 前置公共庫(kù)代碼

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

          五、總結(jié)與展望

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

          [1] 微信小程序的雙線(xiàn)程模型:

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


          瀏覽 56
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  青娱乐澳门久久 | 伊人高清在线 | 爽灬爽灬爽灬高潮无码视频直播 | 亚洲无码不卡视频 | 以前的午夜操一操 |