云音樂前端體驗(yàn)優(yōu)化實(shí)踐
(給前端大學(xué)加星標(biāo),提升前端技能.)
作者:賀文超
https://www.yuque.com/binfe/cquxg7/rh12qe
本次分享主要圍繞云音樂在 C 端性能體驗(yàn)的部分實(shí)踐經(jīng)歷,包括評(píng)估標(biāo)準(zhǔn)和監(jiān)控能力建設(shè),以及在網(wǎng)絡(luò)、容器等方面的性能優(yōu)化實(shí)踐。
團(tuán)隊(duì)面臨的挑戰(zhàn)
云音樂從19年初開始,前端從落地頁、APP 內(nèi)長(zhǎng)尾頁面的開發(fā),逐步承擔(dān)起 APP 內(nèi)部分新業(yè)務(wù)場(chǎng)景的開發(fā)職責(zé)。

這個(gè)階段,網(wǎng)頁的使用體驗(yàn)也逐漸受到外部的關(guān)注。由于網(wǎng)頁和客戶端頁面的原生體驗(yàn)上有所差別,加之前端團(tuán)隊(duì)的體驗(yàn)意識(shí)尚弱,部分業(yè)務(wù)上線后收到了一些負(fù)面反饋,前端在技術(shù)選型上也受到諸多挑戰(zhàn)。
因此我們意識(shí)到,團(tuán)隊(duì)急需思考和解決頁面體驗(yàn)的問題。而面對(duì)多產(chǎn)品和業(yè)務(wù)線的團(tuán)隊(duì)結(jié)構(gòu),要做到體驗(yàn)問題在整個(gè)團(tuán)隊(duì) 有標(biāo)準(zhǔn)、能發(fā)現(xiàn)、快解決,對(duì)于工程化能力會(huì)有較高的要求。
體驗(yàn)工程化
為了解決前端交付體驗(yàn)問題,我們首要的事情是統(tǒng)一體驗(yàn)的度量標(biāo)準(zhǔn),并輔以自動(dòng)化的發(fā)現(xiàn)、反饋、追蹤流程,包括:
前端應(yīng)用能夠自動(dòng)接入性能監(jiān)控,以達(dá)到100%的監(jiān)控覆蓋率
監(jiān)控系統(tǒng)實(shí)時(shí)收集網(wǎng)頁上報(bào)的性能數(shù)據(jù),并對(duì)頁面的收錄和實(shí)驗(yàn)室環(huán)境測(cè)試,結(jié)合度量標(biāo)準(zhǔn)對(duì)頁面進(jìn)行評(píng)估,針對(duì)不達(dá)標(biāo)的頁面實(shí)時(shí)預(yù)警。
監(jiān)控系統(tǒng)對(duì)問題進(jìn)行持續(xù)追蹤和反饋,推進(jìn)開發(fā)解決體驗(yàn)問題。
我們希望通過這個(gè)流程逐步建立起從發(fā)現(xiàn)問題到解決問題、復(fù)盤沉淀的良性循環(huán),持續(xù)提高團(tuán)隊(duì)優(yōu)秀體驗(yàn)應(yīng)用的交付能力。
體驗(yàn)度量標(biāo)準(zhǔn)化
度量標(biāo)準(zhǔn)的選擇
一套完善的度量評(píng)估標(biāo)準(zhǔn),首先要有對(duì)好壞的定義。由于用戶感官性能是當(dāng)下首要關(guān)注的內(nèi)容,因此在標(biāo)準(zhǔn)的選擇上我們對(duì)比了與此相關(guān)的度量模型和工具鏈:
Lighthouse 5.x(19年)
Lighthouse 這款工具基于預(yù)設(shè)環(huán)境來提供性能評(píng)估模型和分析。其中 5.x 版本的評(píng)估模型包含6個(gè)維度,不同維度在性能上權(quán)重不同。它的特點(diǎn)是:
在預(yù)設(shè)環(huán)境進(jìn)行測(cè)試,排除各種設(shè)備、環(huán)境因素,關(guān)注純代碼側(cè)性能。
評(píng)估模型盡量體現(xiàn)用戶真實(shí)的感官體驗(yàn),而不是單純的加載速度。另外模型和算法會(huì)不斷優(yōu)化完善。
能夠評(píng)估第三方頁面(可以幫助我們對(duì)比和外部頁面的差異)。
提供包含優(yōu)化建議的分析報(bào)告。
為了解決開發(fā)在本地測(cè)試中硬件、網(wǎng)絡(luò)情況不一致導(dǎo)致的問題,我們搭建了內(nèi)部的 Lighthouse 測(cè)試服務(wù),用相同配置的一組測(cè)試機(jī)進(jìn)行前后一致的測(cè)試。同時(shí)設(shè)置了統(tǒng)一的 CPU 和網(wǎng)絡(luò)模擬限制,來達(dá)到較好的結(jié)果對(duì)比度。

Performance API
W3C 定義的三個(gè) Performance API 提供真實(shí)環(huán)境中各階段時(shí)間節(jié)點(diǎn):
Navigation Timing,網(wǎng)頁各個(gè)階段的時(shí)間節(jié)點(diǎn)
Resource Timing,頁面靜態(tài)資源的加載時(shí)間
Long Tasks,長(zhǎng)耗時(shí)任務(wù)
例如我們前期最關(guān)注的 Navigation Timing,包含了如下圖所示的網(wǎng)頁訪問時(shí)各個(gè)階段的時(shí)間節(jié)點(diǎn)。

Performance API 的特點(diǎn)是:
體現(xiàn)真實(shí)環(huán)境下,各種綜合因素下的性能表現(xiàn)。
維度為各個(gè)階段時(shí)間的具體開銷,相對(duì) Lighthouse 指標(biāo)更加穩(wěn)定。
需要主動(dòng)上報(bào),適用于內(nèi)部頁面測(cè)試。
Lighthouse 為主的度量標(biāo)準(zhǔn)
我們選擇了以 Lighthouse 為主進(jìn)行度量,Performance API 和其他手段為輔的方式。
其中體驗(yàn)基線(及格線)的定義是在如下 CPU 和網(wǎng)絡(luò)統(tǒng)一限制環(huán)境下,Lighthouse 測(cè)試穩(wěn)定達(dá)到80分+:

由于基線只能反映前端研發(fā)側(cè)的性能質(zhì)量,而無法評(píng)估到容器、網(wǎng)絡(luò)等真實(shí)環(huán)境因素。因此在及格線之外,我們補(bǔ)充了其他指標(biāo),以便結(jié)合數(shù)據(jù)進(jìn)行網(wǎng)絡(luò)、容器等方面的通用能力優(yōu)化。包括 Performance API 各個(gè)階段數(shù)據(jù)、頁面秒開率、容器初始化時(shí)間等。
選擇 Lighthouse 為主的度量標(biāo)準(zhǔn)主要依據(jù)是:
易于理解。由于 Lighthouse 排除真實(shí)環(huán)境中硬件、網(wǎng)絡(luò)等干擾因素,關(guān)注純開發(fā)側(cè)性能, 能夠拿到開發(fā)易于理解、對(duì)優(yōu)化有直觀幫助的指標(biāo)數(shù)據(jù)。
關(guān)注用戶真實(shí)體驗(yàn)。Lighthouse 面向感官性能,而不只關(guān)注加載快慢,這和我們關(guān)注用戶真實(shí)體驗(yàn)的原則一致。
有助于團(tuán)隊(duì)快速形成正向循環(huán)。性能分析報(bào)告和優(yōu)化建議有助于團(tuán)隊(duì)在之前積累不足的背景下快速獲得體驗(yàn)優(yōu)化的正向反饋。
由于能夠評(píng)估第三方頁面,方便我們了解當(dāng)前行業(yè)的整體情況,進(jìn)行橫向評(píng)估和對(duì)比。
基于 Web Vitals 的新標(biāo)準(zhǔn)
標(biāo)準(zhǔn)不是一成不變的,2020年5月在 Google 提出了 Web Vitals 后,我們也補(bǔ)充收集了這部分?jǐn)?shù)據(jù)。
Web Vitals 是 Google 面向未來的性能度量重心。為了進(jìn)一步減少開發(fā)者的理解成本,它的核心理念是網(wǎng)站開發(fā)者不一定要成為性能優(yōu)化專家。
首先, Web Vitals 基于更易標(biāo)準(zhǔn)化、更加貼近用戶真實(shí)感受的原則對(duì)指標(biāo)進(jìn)行了升級(jí),并在指標(biāo)之上定義了 Core Web Vitals,開發(fā)者只需要聚焦在最核心的三個(gè)指標(biāo)上。

另外,這些指標(biāo)被集成到了更多的工具中,包括 Lighthouse、新版本的Chromium 內(nèi)核瀏覽器等。這樣便可以統(tǒng)一線上和實(shí)驗(yàn)室環(huán)境中性能測(cè)試的度量衡,解決了之前不同工具測(cè)試標(biāo)準(zhǔn)不一致而帶來的諸多問題。
目前我們已經(jīng)能夠收集到各個(gè)工具鏈的 Web Vitals 數(shù)據(jù),目前在評(píng)估觀察中。后續(xù)或許會(huì)基于 Core Web Vitals 對(duì)體驗(yàn)基線進(jìn)行升級(jí)。
體驗(yàn)評(píng)估體系
自動(dòng)接入性能監(jiān)控系統(tǒng)
由于團(tuán)隊(duì)有統(tǒng)一的發(fā)布系統(tǒng)作為收斂點(diǎn),在發(fā)布系統(tǒng)新建應(yīng)用時(shí),可以為所有應(yīng)用自動(dòng)接入性能監(jiān)控系統(tǒng)。

應(yīng)用創(chuàng)建時(shí),發(fā)布系統(tǒng)自動(dòng)在相關(guān)平臺(tái)上生成唯一標(biāo)志,后續(xù)每次應(yīng)用構(gòu)建時(shí),自動(dòng)在 HTML 頁面中插入相應(yīng) SDK 的下載邏輯即可。

同時(shí),已發(fā)布的應(yīng)用也可以在發(fā)布系統(tǒng)上通過同樣的方式一鍵接入監(jiān)控系統(tǒng)。
自動(dòng)收錄頁面并測(cè)試
我們希望這些接入了性能監(jiān)控 SDK 的頁面能夠被自動(dòng)收錄并進(jìn)行 Lighthouse 測(cè)試。
線上應(yīng)用接入性能監(jiān)控 SDK 后,真實(shí)用戶訪問頁面時(shí)會(huì)上報(bào)性能數(shù)據(jù)。我們能夠基于這些數(shù)據(jù)收集到所有被訪問過的真實(shí) URL,并通過一定規(guī)則將同類頁面進(jìn)行聚合。
對(duì)單日 PV 達(dá)到一定數(shù)量的聚類,選取任一真實(shí)鏈接進(jìn)行收錄。
最后通過定時(shí)服務(wù)對(duì)收錄的頁面進(jìn)行定期測(cè)試。

這樣便完成了線上頁面的全量收錄和定時(shí)測(cè)試。
頁面評(píng)估、預(yù)警、指引
每次測(cè)試后都會(huì)生成 Lighthouse 分析報(bào)告,我們針對(duì)一段時(shí)間內(nèi)多次測(cè)試未達(dá)基線的頁面推送郵件預(yù)警,并提供相應(yīng)的優(yōu)化建議,引導(dǎo)頁面負(fù)責(zé)人進(jìn)行優(yōu)化改進(jìn)。
持續(xù)追蹤和反饋
通過實(shí)時(shí)預(yù)警和定期的郵件推送,開發(fā)能夠持續(xù)了解到所負(fù)責(zé)前端應(yīng)用的體驗(yàn)問題。
另外團(tuán)隊(duì)的體驗(yàn)大盤也提供了實(shí)時(shí)的團(tuán)隊(duì)整體概況和走勢(shì),并通過標(biāo)桿應(yīng)用、排行榜透出等等提高體驗(yàn)問題的曝光度。
長(zhǎng)期上,我們通過雙線組織促進(jìn)團(tuán)隊(duì)研發(fā)能力的養(yǎng)成:
體驗(yàn)小分隊(duì)作為虛擬組織,負(fù)責(zé)平臺(tái)能力提供和橫向信息拉齊。
各業(yè)務(wù)小組負(fù)責(zé)業(yè)務(wù)內(nèi)應(yīng)用的實(shí)際優(yōu)化和能力沉淀等等。
應(yīng)用側(cè)體驗(yàn)優(yōu)化效果
經(jīng)過多個(gè)季度的努力,前端應(yīng)用在體驗(yàn)方面的交付質(zhì)量有了顯著的提升。

基于動(dòng)靜分離的優(yōu)化實(shí)踐
前端業(yè)務(wù)側(cè)的體驗(yàn)優(yōu)化是最基礎(chǔ)、也是最重要的一環(huán)。然而網(wǎng)頁的性能體驗(yàn)受到網(wǎng)絡(luò)、容器等因素的綜合影響,針對(duì)代碼側(cè)的單一優(yōu)化必然存在難以跨越的性能上限。以云音樂業(yè)務(wù)來看,即使是優(yōu)化過的前端應(yīng)用,真實(shí)場(chǎng)景下收集到的 domReady 均值依然超過 1s。所以我們提出了全鏈路體驗(yàn)優(yōu)化的計(jì)劃,關(guān)注到容器初始化開始的整個(gè)加載過程。
動(dòng)靜分離是穩(wěn)定性保障和性能優(yōu)化中常見的措施。例如在前端開發(fā)中,我們?yōu)殪o態(tài)資源設(shè)置長(zhǎng)期緩存,以便能減輕服務(wù)器壓力并縮短二次訪問的鏈路。而在容器和網(wǎng)絡(luò)階段的優(yōu)化中,我們也可以利用此思想,將相對(duì)穩(wěn)定的內(nèi)容提前下載和執(zhí)行,從而減少用戶真實(shí)操作到來時(shí)的開銷。
本次也將重點(diǎn)分享與動(dòng)靜分離相關(guān)的兩項(xiàng)優(yōu)化措施。
利用 CDN 進(jìn)行網(wǎng)絡(luò)優(yōu)化
通過將內(nèi)容分發(fā)至全球的海量加速節(jié)點(diǎn),使用戶可以就近獲取內(nèi)容,提高網(wǎng)絡(luò)穩(wěn)定性和性能。
幾乎每個(gè)公司在靜態(tài)資源(靜態(tài)網(wǎng)頁、CSS、JS、圖片、媒體資源等)的分發(fā)上都應(yīng)用了 CDN,其實(shí)在動(dòng)態(tài)應(yīng)用(或者動(dòng)靜混合型應(yīng)用)中, CDN 也能夠在性能和穩(wěn)定性方面發(fā)揮很好的作用。因此我們?yōu)?SSR 應(yīng)用中動(dòng)態(tài)生成的 HTML 也提供了 CDN 域名。網(wǎng)頁上 CDN 可能帶來的性能優(yōu)化包括:
建連時(shí)間優(yōu)化
回源路徑優(yōu)化(理論收益)
緩存帶來的收益(針對(duì)可緩存資源)
動(dòng)靜分離
由于 SSR 應(yīng)用經(jīng)歷了服務(wù)端渲染的過程。如果要設(shè)置緩存,首先需要對(duì)頁面內(nèi)容進(jìn)行動(dòng)靜分離。SSR 應(yīng)用中,如果頁面上的某個(gè)內(nèi)容滿足以下條件,就可以認(rèn)為該內(nèi)容是可靜態(tài)化的:
允許一段時(shí)間的時(shí)效性問題
不因人而異(與用戶態(tài)不相關(guān))
不因設(shè)備而異
舉個(gè)例子,如果對(duì)視頻詳情頁進(jìn)行動(dòng)靜分離,可以將視頻基本內(nèi)容作為靜態(tài)內(nèi)容、其他內(nèi)容作為動(dòng)態(tài)內(nèi)容。

遵循源站的設(shè)置
動(dòng)靜混合型應(yīng)用的每個(gè)頁面可能對(duì)時(shí)效性的要求不同,如果一個(gè)頁面絕大部分內(nèi)容都是動(dòng)態(tài)的則不能設(shè)置緩存。所以不同于靜態(tài)應(yīng)用可以設(shè)置固定的緩存時(shí)長(zhǎng),動(dòng)態(tài)應(yīng)用的 CDN 緩存策略需要遵循源站,由服務(wù)端為每個(gè)頁面設(shè)置合適的緩存時(shí)長(zhǎng)。

優(yōu)化效果
網(wǎng)頁上 CDN 的收益主要集中在建連時(shí)間和內(nèi)容傳輸時(shí)間的優(yōu)化上,內(nèi)部應(yīng)用實(shí)際上能夠帶來60-100ms左右的提升。由于這個(gè)收益覆蓋了絕大多數(shù)域名,所以整體收益還是比較可觀的。

另外在穩(wěn)定性保障和優(yōu)雅降級(jí)上,CDN 也有良好的表現(xiàn)。例如在服務(wù)不可用時(shí),用戶也可以看到較為友好的頁面:

公共資源預(yù)加載
在云音樂 APP 內(nèi),前端應(yīng)用以 CSR 頁面為主,這使端內(nèi)有更大的空間進(jìn)行預(yù)處理工作。另外云音樂分散的部署模式導(dǎo)致絕大部分前端應(yīng)用為小型應(yīng)用,每個(gè)頁面中 React 等公共代碼占了大部分。
基本思路
因此我們想到,通過代碼的動(dòng)靜分離將應(yīng)用無關(guān)的公共部分單獨(dú)打包,并提前加載執(zhí)行??梢蕴崆巴瓿纱蟛糠执a的下載和執(zhí)行開銷。

公共資源包會(huì)在 APP 預(yù)加載容器中提前預(yù)熱執(zhí)行,在用戶真實(shí)訪問到來時(shí),只需要加載剩余的代碼?;玖鞒倘缦拢?/p>
APP 啟動(dòng)時(shí)預(yù)創(chuàng)建 Webview
Webview 預(yù)加載引用了公共資源包代碼的空白 HTML
用戶訪問時(shí),如果命中某個(gè)公共包則復(fù)用 Webview,后續(xù)只需要做加載剩余業(yè)務(wù)代碼、糾正地址欄等操作即可
每消耗一個(gè) Webview 對(duì)象,就重新創(chuàng)建一個(gè)
優(yōu)化效果
目前公共資源預(yù)加載方式的應(yīng)用能夠獲得 40%+ 的時(shí)間優(yōu)化。下圖是某頁面的優(yōu)化前后對(duì)比:

擴(kuò)展場(chǎng)景
對(duì)于應(yīng)用的性能提升效果,實(shí)際上與公共部分在業(yè)務(wù)應(yīng)用代碼中的占比有關(guān)系。由于我們可以同時(shí)支持多個(gè)公共資源包預(yù)加載,因此針對(duì)核心的垂直場(chǎng)景,可以擴(kuò)展為完整代碼的預(yù)加載優(yōu)化,從而節(jié)省 100% 的代碼執(zhí)行開銷。

小結(jié)
今天主要和大家分享了云音樂在 C 端性能體驗(yàn)的一部分實(shí)踐經(jīng)歷,包括評(píng)估標(biāo)準(zhǔn)和監(jiān)控能力建設(shè),以及在網(wǎng)絡(luò)、容器等方面的性能優(yōu)化實(shí)踐。由于篇幅原因僅包含了部分實(shí)踐內(nèi)容,歡迎大家針對(duì)前端體驗(yàn)相關(guān)的問題繼續(xù)交流探討。
??愛心三連擊
點(diǎn)分享 點(diǎn)點(diǎn)贊 點(diǎn)在看



