2021 年 Web 核心性能指標(biāo)是什么?谷歌工程師告訴你,F(xiàn)MP 過時啦!
性能指標(biāo)對于網(wǎng)站來說是一個長期需要努力優(yōu)化提升的目標(biāo),谷歌為此推出了一系列工具,本文我想給大家介紹 web-vitals[1]這個由谷歌工程師編寫的小而美的性能指標(biāo)測量 sdk。
本文是 ssh 整理來自 web-vitals 官網(wǎng)的一些內(nèi)容,感謝谷歌工程師們在性能方面編寫的如此優(yōu)秀的資料。
如何定義性能模型
先講講性能,谷歌提出了著名的 RAIL 模型:
RAIL
分別對應(yīng)響應(yīng)、動畫、空閑和加載,自上而下的在各個步驟延伸出各種優(yōu)化手段,具體的各階段介紹可以看 Measure performance with the RAIL model[2] 這篇文章,本文主要專注于講解如何去定義這些階段的性能好壞。
性能監(jiān)控的種類
然后需要了解一下性能監(jiān)控的種類,性能監(jiān)控分為兩種:
- 合成監(jiān)控(Synthetic Monitoring,SYN)是一種模擬網(wǎng)頁加載或者腳本運(yùn)行來測量性能指標(biāo)的方式,輸出網(wǎng)頁性能報告。這種方式的價值在于提前發(fā)現(xiàn)可能存在的性能問題,不依賴于用戶上報。Lighthouse[3] 就是谷歌開發(fā)的非常著名的一種合成測試工具,它既可以作為瀏覽器插件運(yùn)行,也可以作為 cli 腳本,甚至以程序化的方式運(yùn)行在你的 Node.js 代碼中。
- 真實用戶監(jiān)控(Real User Monitoring,RUM)是記錄用戶真實操作的一種被動監(jiān)控,它的特點是用戶真實的網(wǎng)頁交互中去評估和記錄性能數(shù)據(jù)。比如咱們常說的性能監(jiān)控 sdk,就是為此而引入的。本文所介紹的 web-vitals 正是為了這種類型的監(jiān)控而生。
合成監(jiān)控和真實用戶監(jiān)控相輔相成,前者用于在實驗室環(huán)境下提前發(fā)現(xiàn)一些性能問題;后者則深入到真實世界,和用戶設(shè)備、網(wǎng)速、環(huán)境等息息相關(guān)。
在此前提之下,谷歌也把性能指標(biāo)分為兩類:
- 實驗室指標(biāo)(In the lab):使用工具在一致的環(huán)境中模擬頁面加載。
- 真實指標(biāo)(In the field):在真實用戶環(huán)境中加載并且和用戶交互。
核心性能指標(biāo)
Web Vitals 其實是谷歌發(fā)起的一項倡議,統(tǒng)一關(guān)鍵性能的標(biāo)準(zhǔn),幫助網(wǎng)站開發(fā)者去統(tǒng)計最重要的指標(biāo),簡化了許多復(fù)雜的概念。
基于長期以來的性能指標(biāo)優(yōu)化體驗,最新的性能指標(biāo)主要專注于加載、交互、視覺穩(wěn)定,綜合下來就是下面的 3 個指標(biāo):
核心性能指標(biāo)
- Largest Contentful Paint (LCP)[4]: 最大內(nèi)容繪制,是用來測量加載的性能。最好保證在 2.5 秒以內(nèi)出現(xiàn)。
- First Input Delay (FID)[5]: 第一次輸入延遲,用于測量可交互性。應(yīng)該在 100 毫秒以內(nèi)。
- Cumulative Layout Shift (CLS)[6]:累計布局位移,用于測量視覺穩(wěn)定性。這個指標(biāo)應(yīng)該小于 0.1。
很多國內(nèi)的文章會提到 First Meaningful Paint (FMP),也就是首次有意義的渲染,但是這個指標(biāo)其實已經(jīng)在 Lighthouse 6.0 中被廢棄了,原因在于頁面的任何細(xì)微差異對這個指標(biāo)的影響都太大了,帶來了雙峰分布(bimodal distribution)的不一致性問題。而且這個測量太依賴瀏覽器的實現(xiàn)細(xì)節(jié)了,意味著沒法在所有瀏覽器中標(biāo)準(zhǔn)化。
目前可以使用 Largest Contentful Paint (LCP)[7] 來替代它。
測量核心指標(biāo)
這些核心指標(biāo),目前都可以利用 web APIs 在 JavaScript 中進(jìn)行測量。
使用 web-vitals
為了封裝一些細(xì)節(jié)差異,谷歌提供了 GoogleChrome/web-vitals[8] 這個輕巧、準(zhǔn)備好用于生產(chǎn)的包,它只是 web APIs 的一層封裝,用戶不需要再關(guān)心指標(biāo)的收集時機(jī),環(huán)境判斷等問題。
- import { getCLS, getFID, getLCP } from "web-vitals";
- function sendToAnalytics(metric) {
- const body = JSON.stringify(metric);
- // Use `navigator.sendBeacon()` if available, falling back to `fetch()`.
- (navigator.sendBeacon && navigator.sendBeacon("/analytics", body)) ||
- fetch("/analytics", { body, method: "POST", keepalive: true });
- }
- getCLS(sendToAnalytics);
- getFID(sendToAnalytics);
- getLCP(sendToAnalytics);
拿到了這些性能數(shù)據(jù)以后,你就可以自己清洗、整理并統(tǒng)計生成可視化的視圖,當(dāng)然你也可以用谷歌的 GoogleChromeLabs/web-vitals-report[9] 來生成可視化的數(shù)據(jù)看板。
手動測量
當(dāng)然,你也可以利用底層 web APIs 來手動測量,但是這就需要你自己決定上報的時機(jī)還有收集的次數(shù)等等。
LCP
- new PerformanceObserver((entryList) => {
- for (const entry of entryList.getEntries()) {
- console.log("LCP candidate:", entry.startTime, entry);
- }
- }).observe({ type: "largest-contentful-paint", buffered: true });
FID
- new PerformanceObserver((entryList) => {
- for (const entry of entryList.getEntries()) {
- const delay = entry.processingStart - entry.startTime;
- console.log("FID candidate:", delay, entry);
- }
- }).observe({ type: "first-input", buffered: true });
CLS
- let cls = 0;
- new PerformanceObserver((entryList) => {
- for (const entry of entryList.getEntries()) {
- if (!entry.hadRecentInput) {
- cls += entry.value;
- console.log("Current CLS value:", cls, entry);
- }
- }
- }).observe({ type: "layout-shift", buffered: true });
前兩者直接利用了 PerformanceObserver[10] 的指定 type 即可。CLS 相對特殊一些,因為是頁面布局的累計位移,所以要一直監(jiān)聽并且疊加這個值。
手動測量的缺點在于,你需要自己遵循 Web Vitals 的測量標(biāo)準(zhǔn)去在相應(yīng)的時機(jī)開始、結(jié)束測量,而且很多邊界情況也需要你自己處理。
如何優(yōu)化核心性能指標(biāo)
當(dāng)你測量了網(wǎng)站的核心性能指標(biāo)之后,下一步就是優(yōu)化它們。這幾篇文章可以給你很好的指導(dǎo):
- Optimize Largest Contentful Paint[11]
- Optimize First Input Delay[12]
- Optimize Cumulative Layout Shift[13]
其他性能指標(biāo)
雖然核心性能指標(biāo)是提供優(yōu)秀的用戶體驗的關(guān)鍵,但也還有其他重要的指標(biāo)。
比如 Time to First Byte (TTFB) —— 首字節(jié)時間[14]和 First Contentful Paint (FCP) —— 首次內(nèi)容渲染[15] 對于加載體驗來說都很重要,對于診斷 LCP 來說也很實用(比如服務(wù)器速度過慢,或者有阻塞渲染的資源)。
類似的還有 Total Blocking Time (TBT) —— 總阻塞時間[16] 和 Time to Interactive (TTI) —— 首次可交互時間[17] ,它們都會影響 FID,是用來分析潛在的可交互性問題的實驗室指標(biāo)。它們并不屬于核心性能指標(biāo),因為它們并不適用于真實環(huán)境測量,也不會反應(yīng)用戶為中心的感受。
不斷發(fā)展的性能指標(biāo)
Web Vitals 和核心性能指標(biāo)代表了當(dāng)今用來衡量 Web 體驗質(zhì)量的最佳可用信號,未來會不斷的發(fā)展和改進(jìn)。
核心性能指標(biāo)和谷歌分析工具以及依賴它的頁面息息相關(guān),更改會產(chǎn)生廣泛的影響。因此,開發(fā)者應(yīng)當(dāng)期望它是穩(wěn)定的,如果要更新的話應(yīng)該預(yù)先通知,并且應(yīng)該是以年為周期、可預(yù)期的更新。
其他性能指標(biāo)通常和特定的工具關(guān)聯(lián),相比起核心性能指標(biāo)更具有實驗性質(zhì),更新的頻率可能會更高。
對于所有指標(biāo)的更新,這個 CHANGELOG[18] 里都會清楚的記錄下來。
參考資料
Measure performance with the RAIL model[19]
Synthetic monitoring - Wikipedia[20]
Real user monitoring - Wikipedia[21]
Web Vitals[22]
User-centric performance metrics[23]
參考資料
[1]
web-vitals: https://github.com/GoogleChrome/web-vitals/
[2]
Measure performance with the RAIL model: https://web.dev/rail/
[3]
Lighthouse: https://github.com/GoogleChrome/lighthouse
[4]
Largest Contentful Paint (LCP): https://web.dev/lcp/
[5]
First Input Delay (FID): https://web.dev/fid/
[6]
Cumulative Layout Shift (CLS): https://web.dev/cls/
[7]
Largest Contentful Paint (LCP): https://web.dev/lcp/
[8]
GoogleChrome/web-vitals: https://github.com/GoogleChrome/web-vitals
[9]
GoogleChromeLabs/web-vitals-report: https://github.com/GoogleChromeLabs/web-vitals-report
[10]
PerformanceObserver: https://developer.mozilla.org/zh-CN/docs/Web/API/PerformanceObserver/PerformanceObserver
[11]
Optimize Largest Contentful Paint: https://web.dev/optimize-lcp/
[12]
Optimize First Input Delay: https://web.dev/optimize-fid/
[13]
Optimize Cumulative Layout Shift: https://web.dev/optimize-cls/
[14]
Time to First Byte (TTFB) —— 首字節(jié)時間: https://web.dev/time-to-first-byte/
[15]
First Contentful Paint (FCP) —— 首次內(nèi)容渲染: https://web.dev/fcp/
[16]
Total Blocking Time (TBT) —— 總阻塞時間: https://web.dev/tbt/
[17]
Time to Interactive (TTI) —— 首次可交互時間: https://web.dev/tti/
[18]
CHANGELOG: https://chromium.googlesource.com/chromium/src/+/master/docs/speed/metrics_changelog/README.md
[19]
Measure performance with the RAIL model: https://web.dev/rail/
[20]
Synthetic monitoring - Wikipedia: https://en.wikipedia.org/wiki/Synthetic_monitoring
[21]
Real user monitoring - Wikipedia: https://en.wikipedia.org/wiki/Real_user_monitoring
[22]
Web Vitals: https://web.dev/vitals/#core-web-vitals
[23]
User-centric performance metrics: https://web.dev/user-centric-performance-metrics