如何做好前端性能監(jiān)控?
大廠技術(shù) 高級(jí)前端 Node進(jìn)階
點(diǎn)擊上方 程序員成長指北,關(guān)注公眾號(hào)
回復(fù)1,加入高級(jí)Node交流群
為什么需要監(jiān)控
眾所周知,性能在提升網(wǎng)站留存率和轉(zhuǎn)化率方面扮演著很重要的角色,尤其對(duì)于轉(zhuǎn)轉(zhuǎn)這種電商網(wǎng)站,性能會(huì)間接影響到公司的收入。
但是如果讓你去描述你們網(wǎng)站應(yīng)用的性能時(shí),你會(huì)怎么回答。你可能會(huì)說:比市面上大部分應(yīng)用要好。但是如果要你說出好在哪里又該如何描述呢?這個(gè)時(shí)候我們就會(huì)想到先對(duì)網(wǎng)站進(jìn)行性能監(jiān)控,用數(shù)據(jù)說話。但是監(jiān)控哪些指標(biāo)、怎么監(jiān)控呢?
監(jiān)控什么
首先需要明確的是我們應(yīng)該監(jiān)控什么,或者說我們應(yīng)該以一個(gè)什么指標(biāo)來度量一個(gè)網(wǎng)站的性能好壞呢?
google 最早提出了一個(gè) RAIL 模型來衡量應(yīng)用性能,即:Response、Animation、Idle、Load,分別代表著 web 應(yīng)用生命周期的四個(gè)不同方面。并指出最好的性能指標(biāo)是:應(yīng)該盡可能快速的響應(yīng)用戶的操作,最好在 100ms 內(nèi);在展示動(dòng)畫的時(shí)候,每一幀應(yīng)該以 16ms 進(jìn)行渲染,這樣可以保持動(dòng)畫效果的一致性,并且避免卡頓;最大化空閑時(shí)間,當(dāng)使用 js 主線程的時(shí)候,應(yīng)該把任務(wù)劃分到執(zhí)行時(shí)間小于 50ms 的片段中去,這樣可以釋放線程以進(jìn)行用戶交互;應(yīng)該在小于 1s 的時(shí)間內(nèi)加載完成你的網(wǎng)站,最長不超過 5 秒。
google 也相對(duì)應(yīng)的制定了一些基于用戶體驗(yàn)的性能指標(biāo)
FCP 首次內(nèi)容繪制時(shí)間(First Contentful Paint):首次內(nèi)容繪制,瀏覽器首次繪制來自 DOM 的內(nèi)容的時(shí)間,內(nèi)容必須包括文本,圖片,非白色的 canvas 或 svg,也包括帶有正在加載中的 web 字體文本。這是用戶第一次看到的內(nèi)容
LCP 最大內(nèi)容繪制時(shí)間 (Largest Contentful Paint):最大內(nèi)容繪制,可視區(qū)域中最大的內(nèi)容元素呈現(xiàn)到屏幕上的時(shí)間,用以估算頁面的主要內(nèi)容對(duì)用戶的可見時(shí)間。img 圖片,video 元素的封面,通過 url 加載到的背景,文本節(jié)點(diǎn)等,為了提供更好的用戶體驗(yàn),網(wǎng)站應(yīng)該在 2.5s 以內(nèi)或者更短的時(shí)間最大內(nèi)容繪制。
FID 首次輸入延遲時(shí)間(First Input Delay):首次輸入延遲,從用戶第一次與頁面進(jìn)行交互到瀏覽器實(shí)際能夠響應(yīng)該交互的時(shí)間,輸入延遲是因?yàn)闉g覽器的主線程正忙于做其他事情,所以不能響應(yīng)用戶,發(fā)生這種情況的一個(gè)常見原因是瀏覽器正忙于解析和執(zhí)行應(yīng)用程序加載的大量計(jì)算的 JavaScript。
TTI 頁面可交互時(shí)間(Time to Interactive):網(wǎng)頁第一次完全達(dá)到可交互狀態(tài)的時(shí)間點(diǎn),瀏覽器已經(jīng)可以持續(xù)的響應(yīng)用戶的輸入,完全達(dá)到可交互的狀態(tài)的時(shí)間是在最后一個(gè)長任務(wù)完成的時(shí)間,并且在隨后的 5 秒內(nèi)網(wǎng)絡(luò)和主線程是空閑的。從定義上來看,中文名稱叫持續(xù)可交互時(shí)間或可流暢交互時(shí)間更合適。
TBT 主線程累計(jì)阻塞時(shí)間(Total Block Time):總阻塞時(shí)間,度量了 FCP 和 TTI 之間的總時(shí)間,在該時(shí)間范圍內(nèi),主線程被阻塞足夠長的時(shí)間以防止輸入響應(yīng)。只要存在長任務(wù),該主線程就會(huì)被視為阻塞,該任務(wù)在主線程上運(yùn)行超過 50 毫秒
CLS 累計(jì)布局偏移 (Cumulative Layout Shift):累計(jì)布局偏移,CLS 會(huì)測(cè)量在頁面整個(gè)生命周期中發(fā)生的每個(gè)意外的布局移位的所有單獨(dú)布局移位分?jǐn)?shù)的總和,他是一種保證頁面的視覺穩(wěn)定性從而提升用戶體驗(yàn)的指標(biāo)方案。
google 后來覺得指標(biāo)有些太多了,就縮減成三個(gè)了,也就是 2020 年提出的 Web Vitals。認(rèn)為網(wǎng)站只要做好加載性能 LCP,交互性 FID,視覺穩(wěn)定性 CLS,基本性能就可以了
轉(zhuǎn)轉(zhuǎn)內(nèi)部也有自己沉淀的一套性能衡量指標(biāo),包含自研的根據(jù) dom 權(quán)重計(jì)算的 FMP 指標(biāo),再配合白屏?xí)r間、秒開率、DOM 加載時(shí)間等綜合來評(píng)定一個(gè)網(wǎng)站的性能優(yōu)劣。
怎么監(jiān)控
有了指標(biāo),接下來我們就需要監(jiān)控。通過監(jiān)控來知道 web 應(yīng)用性能的現(xiàn)狀和趨勢(shì),找到 web 應(yīng)用的瓶頸,提高業(yè)務(wù)的穩(wěn)定性。同時(shí)還能清楚的了解到某次發(fā)布后對(duì)性能的影響,感知到業(yè)務(wù)出錯(cuò)的概率。
目前市面上的主流監(jiān)控分為兩種,一種是合成監(jiān)控,一種是真實(shí)用戶監(jiān)控。
合成監(jiān)控是指在一個(gè)模擬場(chǎng)景里去運(yùn)行你的頁面,然后提取一些性能指標(biāo),得出一個(gè)審計(jì)報(bào)告。另外一種是真實(shí)用戶監(jiān)控:真實(shí)用戶監(jiān)控是一種應(yīng)用服務(wù),被監(jiān)控的 web 應(yīng)用通過 sdk 等方式接入該服務(wù),將真實(shí)的用戶訪問、交互等性能指標(biāo)數(shù)據(jù)收集上報(bào)到我們的日志服務(wù)器上、通過數(shù)據(jù)清洗加工后形成性能分析報(bào)表,最后在我們的監(jiān)控平臺(tái)上進(jìn)行展示
兩種監(jiān)控的對(duì)比
通過對(duì)比這兩種監(jiān)控的優(yōu)劣勢(shì)可以發(fā)現(xiàn)合成監(jiān)控更適合做一些特定場(chǎng)景業(yè)務(wù)下的定性分析,或者配合 CI 做小數(shù)據(jù)量的監(jiān)控,而真實(shí)用戶監(jiān)控則更適合做定量分析,結(jié)合數(shù)據(jù)并進(jìn)行深度挖掘。目前轉(zhuǎn)轉(zhuǎn)對(duì)這兩種監(jiān)控都有不同的實(shí)現(xiàn),分別是我們內(nèi)部的檢測(cè)平臺(tái)以及性能平臺(tái),相輔相成,共同完成對(duì)性能指標(biāo)的監(jiān)控。
用于真實(shí)用戶監(jiān)控的性能平臺(tái)之前公眾號(hào)已有相關(guān)文章闡述,接下來主要介紹下如何進(jìn)行合成監(jiān)控。
合成監(jiān)控-Lighthouse
合成監(jiān)控中最流行的是 Google 的 Lighthouse。Lighthouse 是一個(gè)開源的自動(dòng)化工具,用于分析和改善 Web 應(yīng)用的質(zhì)量。啟動(dòng) Lighthouse 共有 4 種姿勢(shì),分別是 Chrome 開發(fā)者工具,Chrome 擴(kuò)展程序,Node CLI 和 Node module。
以最常用也最為方便的的開發(fā)者工具的方式運(yùn)行 Lighthouse 會(huì)生成一個(gè)如下的報(bào)告。
報(bào)告雖然涵蓋了大部分的指標(biāo),但該方式依然會(huì)存在一些局限:
-
無法檢測(cè)需要登錄的頁面 -
指標(biāo)太多、太雜,無法定制化、差異化 -
沒有接入平臺(tái),無法了解整體概況
目前業(yè)界大部分公司都會(huì)選擇搭建一個(gè)合成監(jiān)控平臺(tái),通過 Node module 以編程的方式來解決上述問題
Lighthouse 運(yùn)行流程
以編程的方式運(yùn)行 Lighthouse,就需要先對(duì) Lighthouse 的運(yùn)行流程做一個(gè)全面的了解
官網(wǎng)給出的架構(gòu)圖中將 Lighthouse 分成了 4 個(gè)模塊,包含 Driver、Gatherers、Audits、Report。
Lighthouse 會(huì)驅(qū)動(dòng) Driver 通過 Chrome DevTool Protocol 協(xié)議 與瀏覽器進(jìn)行交互,執(zhí)行一系列命令,然后通過 Gatherers 模塊采集頁面加載過程中的信息,并生成中間產(chǎn)物 artifacts,這些 artifacts 信息的聚合會(huì)在 Auditing 階段作為 Audit case 邏輯的輸入憑證,通過定義的一系列自定義的審計(jì)標(biāo)準(zhǔn)輸出分?jǐn)?shù)/優(yōu)化/詳情/描述/原因/展示形式/錯(cuò)誤等信息,最終得到一系列的 LHR 統(tǒng)計(jì)結(jié)果并輸出 UI 報(bào)表。
解決問題
流程介紹完了,那么如何基于 Lighthouse 的運(yùn)行流程去解決上述的幾點(diǎn)問題呢?
登錄問題
我們知道,直接使用 Lighthouse 去檢測(cè)需要登錄態(tài)的頁面最終輸出的其實(shí)是登錄頁的檢測(cè)結(jié)果,這顯然不是我們想要的。
好在官方也給我們指明了出路,最方便最靈活的就是使用 Puppeteer 模擬用戶登錄,正好 Puppeteer 也是使用 Chrome DevTool Protocol 協(xié)議,可以無縫切換。
在 Lighthouse 中使用 Puppeteer 有兩種方式,一種是使用 Puppeteer 啟動(dòng)瀏覽器,然后將控制權(quán)交還到 Lighthouse,另外一種是使用 Lighthouse/chrome-launcher 啟動(dòng)瀏覽器,然后將控制權(quán)交還到 Puppeteer。這里我們采用的是第一種方式
個(gè)性化
默認(rèn)的檢測(cè)指標(biāo)只是一個(gè)通用的檢測(cè)模型,實(shí)際情況中我們需要根據(jù)不同的業(yè)務(wù)形態(tài)去制定不同的檢測(cè)模型。比如在 pc 端由于邏輯復(fù)雜,我們可能會(huì)寫很多的嵌套組件,那么構(gòu)建 dom 數(shù)的深度就是一個(gè)需要關(guān)注的指標(biāo)了;而在移動(dòng)端,我們可能更加的聚焦于性能和體驗(yàn),那么頁面是否有橫向滾動(dòng)條就是一個(gè)需要關(guān)注的指標(biāo)了。
如何去收集這些指標(biāo)信息呢?答案就在 Lighthouse 的 Gatherers 模塊。
每一個(gè) gatherer 都繼承自相同的父類 Gatherer,其中定義了三個(gè)模板方法,子類只需實(shí)現(xiàn)關(guān)心的模板方法即可
比如我們要收集頁面的 title,可以這么實(shí)現(xiàn)一個(gè) gatherer
當(dāng)所有的 gatherers 運(yùn)行完后,就會(huì)生成一個(gè)中間產(chǎn)物 artifacts,此后 Lighthouse 就可以使用 artifacts 進(jìn)行后續(xù)的分析。
轉(zhuǎn)轉(zhuǎn)初版檢測(cè)模型如下
平臺(tái)化
這個(gè)可以根據(jù)各自公司的 CI/CD 工具進(jìn)行集成,在部署服務(wù)的時(shí)候調(diào)用一下檢測(cè)接口,最后將報(bào)告輸出的 json 數(shù)據(jù)進(jìn)行入庫操作即可
賦能業(yè)務(wù)
開發(fā)完這個(gè)檢測(cè)平臺(tái),想的第一件事就是如何同業(yè)務(wù)相結(jié)合。當(dāng)時(shí)正值公司 618 大促,運(yùn)營人員使用公司內(nèi)部的魔方系統(tǒng)搭建活動(dòng)頁的需求較多,所以專門針對(duì)魔方業(yè)務(wù)制定了一套檢測(cè)模型。
魔方系統(tǒng)主要以圖文展示為主,所以重點(diǎn)就放在圖片的布局偏移、大小、數(shù)量以及錯(cuò)別字檢測(cè)等維度
檢測(cè)出有待優(yōu)化的地方(紅色部分)會(huì)在魔方系統(tǒng)的列表頁中給出提示,督促相關(guān)人員進(jìn)行調(diào)整和修改。
總結(jié)
檢測(cè)平臺(tái)作為一個(gè)輔助性的檢測(cè)系統(tǒng),當(dāng)制定好相關(guān)的檢測(cè)模型后,能方便大家快速定位到性能問題。
參考:
lighthouse 官網(wǎng)
為什么性能如此重要
螞蟻金服如何把前端性能監(jiān)控做到極致?
如何從 0 到 1 搭建性能檢測(cè)系統(tǒng)
我組建了一個(gè)氛圍特別好的 Node.js 社群,里面有很多 Node.js小伙伴,如果你對(duì)Node.js學(xué)習(xí)感興趣的話(后續(xù)有計(jì)劃也可以),我們可以一起進(jìn)行Node.js相關(guān)的交流、學(xué)習(xí)、共建。下方加 考拉 好友回復(fù)「Node」即可。
“分享、點(diǎn)贊、在看” 支持一波??
