以用戶為中心的性能指標是理解和改進站點體驗的關鍵點 一、以用戶為中心的性能指標 1. 指標是用來幹啥的? 指標是用來衡量性能和用戶體驗的 2. 指標類型 感知載入速度:網頁可以多快地載入網頁中的所有視覺元素並將其渲染到屏幕上 載入響應速度:頁面載入和執行組件快速響應用戶互動所需的 JavaScrip... ...
Web 頁面性能衡量指標-以用戶為中心的性能指標
以用戶為中心的性能指標是理解和改進站點體驗的關鍵點
一、以用戶為中心的性能指標
1. 指標是用來幹啥的?
指標是用來衡量性能和用戶體驗的
2. 指標類型
-
感知載入速度:網頁可以多快地載入網頁中的所有視覺元素並將其渲染到屏幕上
-
載入響應速度:頁面載入和執行組件快速響應用戶互動所需的
JavaScript
代碼的速度 -
運行時響應速度:網頁在載入後對用戶互動的響應速度
-
視覺穩定性:頁面上的元素是否會以用戶意想不到的方式發生偏移,是否可能會幹擾用戶的互動?
-
流暢性:過渡和動畫是否以一致的幀速率渲染,併在一種狀態之間流暢地流動?
3. 要衡量的指標
3.1. FCP(First Contentful Paint)
從網頁開始載入到網頁內容的任何部分呈現在屏幕上所用的時間
3.2. LCP(Largest Contentful Paint)
從網頁開始載入到屏幕上呈現最大的文本塊或圖片元素所用的時間
3.3. INP(Interaction to Next Paint)
與網頁進行的每次 tap
、click
或鍵盤互動的延遲時間
並根據交互的數量選擇頁面中最差的交互延遲作為單個代表性值來描述頁面的總體響應性
3.4. TBT(Total Blocking Time)
從 FCP
到可交互時間 (TTI
) 之間的總時長
3.5. CLS(Cumulative Layout Shift)
從頁面開始載入到其生命周期狀態更改為隱藏期間發生的所有意外佈局偏移的累計分數
3.6. TTFB(Time to First Byte)
網路使用資源的第一個位元組響應用戶請求所花費的時間
3.7. FID(First Input Delay)
用戶首次與網頁互動(即,點擊鏈接、點按按鈕或使用由 JavaScript
提供支持的自定義控制項)到瀏覽器實際能夠開始處理事件處理腳本以響應相應互動的時間
二、FCP(First Contentful Paint )
1. 什麼是 FCP?
FCP
:從網頁開始載入到網頁內容的任何部分呈現在屏幕上所用的時間。
首次內容繪製 (FCP
) 是一項以用戶為中心的重要指標,用於衡量感知的載入速度。
它標記了網頁載入時間軸中用戶可以看到屏幕上任何內容的第一個點。
FCP
衡量的是從用戶首次導航到相應網頁到該網頁的任何部分呈現在屏幕上所用的時間。對於此指標,內容是指文本、圖片(包括背景圖片)、<svg>
元素或非白色 <canvas>
元素。
2. FCP
FCP
在第二幀發生,因為這是第一個文本元素渲染到屏幕上的時間
3. 良好的 FCP 是多少時間?
為了提供良好的用戶體驗,網站的 FCP
最好不超過 1.8 秒。
較好的 FCP
值為 1.8 秒或更短。較差超過 3.0 秒。
4. 如何衡量 FCP?
-
Lighthouse
-
Chrome DevTools
5. 衡量 JS 中的 FCP
如需在 JavaScript
中測量 FCP
,需使用 Paint Timing API
5.1. 簡單示例:
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntriesByName('first-contentful-paint')) {
console.log('FCP candidate:', entry.startTime, entry);
}
}).observe({type: 'paint', buffered: true});
5.2. 指標與 API 的區別
-
API
會為後臺標簽頁中載入的網頁分派first-contentful-paint
,但在計算FCP
時應忽略這些網頁。只有當網頁始終在前臺運行時,系統才會考慮首次渲染時間。 -
從往返緩存中恢復網頁時,
API
不會報告first-contentful-paint
,但在這些情況下,應衡量FCP
,因為用戶將它們視為不同的網頁訪問。 -
API
可能不會報告跨源iframe
的繪製時間,但為了正確衡量FCP
,必須考慮所有幀。子幀可以使用該API
將其繪製時間報告給父幀以進行彙總。 -
API
從導航啟動時開始測量FCP
,但對於預渲染的網頁,應通過activationStart
測量FCP
。
5.3. 使用 web-vitals JavaScript 庫來衡量 FCP
使用 web-vitals JavaScript
庫來衡量 FCP
,而無需記住所有這些細微差異,該庫會儘可能處理這些差異
import {onFCP} from 'web-vitals';
onFCP(console.log);
onFCP
源碼
6. 如何提高 FCP?
6.1. 提高特定網站的 FCP
可以運行 Lighthouse
性能審核,並關註審核建議的任何特定 opportunities
或者 diagnostics
。
6.2. 總體提高 FCP
-
移除阻塞渲染的資源
-
縮減
CSS
大小 -
移除未使用的
CSS
-
移除未使用的
JavaScript
-
預先連接到所需的源
-
縮短伺服器響應時間 (
TTFB
) -
避免多次網頁重定向
-
預載入密鑰請求
-
避免網路負載龐大
-
採用高效的緩存政策提供靜態資源
-
避免
DOM
規模過大 -
最大限度地縮短關鍵請求深度
-
確保文本在網頁字體載入期間保持可見狀態
-
儘量減少請求數量,減少傳輸大小
三、LCP(Largest Contentful Paint )
1. 什麼是 LCP?
LCP
:從網頁開始載入到屏幕上呈現最大的文本塊或圖片元素所用的時間
LCP
報告的是視窗中可見最大圖片或文本塊相對於用戶首次導航到網頁的呈現時間
LCP
包含從上一個網頁開始的所有卸載時間、連接設置時間、重定向時間和首位元組時間 (TTFB
)
2. 良好的 LCP 是多少時間?
為了提供良好的用戶體驗,網站應努力將 LCP
控制在 2.5 秒以內。
2.5 s 或者更短
3. 需要考慮哪些元素?
Largest Contentful Paint
考慮的元素類型包括:
-
<img>
元素(第一幀呈現時間用於GIF
或動畫PNG
等動畫內容) -
<svg>
元素內的<image>
元素 -
<video>
元素(系統會使用視頻的海報圖片載入時間或第一幀顯示時間,以較早者為準) -
一個元素,帶有使用
url()
函數載入的背景圖片 -
包含文本節點或其他內嵌級文本元素子元素的塊級元素。
後面可能會增加其他元素
4. 如何確定元素的大小?
為 LCP
報告的元素的大小通常是用戶在視窗中可見的大小,如果元素延伸到視窗之外,或者元素被剪切或有不可見的溢出,這些部分不計入元素的大小。
對於根據固有尺寸調整過大小的圖片元素,報告的尺寸為可見尺寸或固有尺寸(以較小者為準)。
對於文本元素,LCP
只會考慮能夠包含所有文本節點的最小矩形。
對於所有元素,LCP
都不會考慮使用 CSS
應用的外邊距、內邊距或邊框。
5. 什麼時候報告 LCP?
網頁通常會分階段載入,因此,網頁上最大的元素可能會發生變化。
為了應對這種可能發生的變化,瀏覽器在繪製完第一幀後,會立即分派 largest-contentful-paint
類型的 PerformanceEntry
,用於標識鏈接最大的內容元素,在渲染後續幀後,只要最大內容元素髮生變化,它就會再分派一個 PerformanceEntry
元素只有在呈現並對用戶可見後,才能被視為最大的內容元素。尚未載入的圖片不會被視為已渲染。在字體屏蔽期間,文本節點也不會使用網頁字體。在這種情況下,系統可能會將較小的元素報告為最大的內容元素,但如果這個較大的元素呈現完畢,系統便會創建另一個 PerformanceEntry
除了延遲載入圖片和字體之外,網頁還可能會在新內容可用時向 DOM
添加新元素。如果這些新元素中的任何一個大於之前的最大內容元素,系統還會報告新的 PerformanceEntry
如果從視窗甚至 DOM
中移除了最大的內容元素,除非渲染了較大的元素,否則它仍然是最大的內容元素
一旦用戶與網頁互動(通過點按、滾動或按鍵),瀏覽器就會停止報告,因為用戶互動通常會改變向用戶顯示的內容(特別是滾動時)。
6. 如何衡量 LCP?
7. 在 JS 中衡量 LCP
7.1. 簡單示例
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
console.log('LCP candidate:', entry.startTime, entry);
}
}).observe({type: 'largest-contentful-paint', buffered: true});
7.2. 指標與 API 的區別
-
API
將為後臺標簽頁中載入的頁面分派largest-contentful-paint
,但在計算LCP
時應忽略這些頁面。 -
在頁面進入後臺後,
API
將繼續分派largest-contentful-paint
,但在計算LCP
時應忽略這些(只有在頁面始終在前臺運行時才可以考慮元素)。 -
從往返緩存中恢復網頁時,該
API
不會報告largest-contentful-paint
,但應在在這些情況下衡量LCP
,因為用戶對它們的訪問體驗是不同的。 -
API
不會考慮iframe
中的元素,但該指標會考慮,因為它們是網頁用戶體驗的一部分。 -
API
從導航開始就測量LCP
,但對於預渲染的網頁,LCP
應從activationStart
開始測量,因為LCP
對應於用戶實際體驗到的LCP
時間。
7.3. 使用 web-vitals JavaScript 庫衡量 LCP
可以使用 web-vitalsJavaScript
庫來衡量 LCP
,而無需記住所有這些細微差異
import {onLCP} from 'web-vitals';
onLCP(console.log);
onLCP
源碼
8. 如何提高 LCP?
- 消除載入延遲
- 消除元素渲染延遲
- 縮短資源載入時長
- 縮短第一個位元組所用的時間
四、INP(Interaction to Next Paint )
1. 什麼是 INP?
INP
:與網頁進行的每次 tap
、click
或鍵盤互動的延遲時間
良好的響應速度意味著網頁對互動的響應速度很快。
當網頁響應互動時,瀏覽器會在所繪製的下一幀中提供_視覺反饋。
有些互動自然會比其他互動花費更長的時間,但對於特別複雜的互動,必須快速提供一些初始視覺反饋,讓用戶知道正在發生的事情。
INP
的目的不是測量互動的所有最終效果,而是下一次繪製被阻止的時間。通過延遲視覺反饋,用戶可能會覺得頁面響應速度不夠快,而 INP 旨在幫助開發者衡量這部分用戶體驗。
2. INP
3. 良好的 INP 是多少時間?
一般 200 ms 以內
-
INP
低於或等於 200 毫秒表示網頁響應良好。 -
INP
高於 200 毫秒且低於或等於 500 毫秒表示網頁的響應能力需要改進。 -
INP
高於 500 毫秒表示網頁響應速度很差。
4. 什麼是互動?
互動的主要驅動因素通常是 JavaScript
,但瀏覽器確實會通過並非由 JavaScript
提供支持的控制項(例如覆選框、單選按鈕和由 CSS
提供支持的控制項)提供互動性。
就 INP
而言,只觀察以下互動類型:
- 使用滑鼠點擊。
- 點按帶有觸摸屏的設備。
- 按實體鍵盤或屏幕鍵盤上的某個鍵。
互動發生在主文檔或文檔內嵌的 iframe
中。
系統會在用戶離開頁面時計算該頁面的 INP
。結果會得到一個能夠代表網頁在其整個生命周期內的整體響應能力的值。INP
較低意味著網頁能夠可靠地響應用戶輸入。
5. INP 與 First Input Delay (FID) 有何不同?
INP
是 First Input Delay (FID)
的繼任指標。雖然兩者都是響應速度指標,但 FID
僅衡量了網頁上首次互動的輸入延遲。INP
通過觀察網頁上的所有互動來改進 FID
,即從輸入延遲開始,到運行事件處理腳本所需的時間,再到瀏覽器繪製下一幀。
這些差異意味著 INP
和 FID
是不同類型的響應能力指標。FID
是用於評估網頁對用戶的首次展示的載入響應速度指標,而無論網頁互動在何時發生,INP
都是更可靠的整體響應能力指標。
6. 如果未報告 INP 值,該怎麼辦?
網頁可能不會返回任何 INP
值。導致這種情況的原因可能有很多,其中包括以下原因:
- 頁面已載入,但用戶從未點擊、點按或按鍵盤上的鍵。
- 網頁已載入,但用戶使用不衡量的手勢與網頁互動。
- 該網頁正被機器人訪問,但該機器人尚未編寫與該網頁交互的腳本。
7. 如何改進 INP?
-
優化耗時較長的任務
-
優化輸入延遲
-
腳本評估和耗時較長的任務
-
使用
Web Worker
在瀏覽器的主線程之外運行JavaScript
-
避免大型、複雜的佈局和佈局抖動
-
縮小樣式計算的範圍並降低其複雜性
五、 TBT(Total Blocking Time)
1. 什麼是 TBT?
TBT
:總阻塞時間,從 FCP
到可交互時間 (TTI
) 之間的總時長,其中主線程處於阻塞狀態的時間足夠長,足以阻止輸入響應能力。
每當存在長任務(一種在主線程上運行時間超過 50 毫秒 (ms
) 的任務)時,主線程就會被視為阻塞。
我們說主線程處於阻塞狀態,因為瀏覽器無法中斷正在進行的任務。如果用戶嘗試在耗時較長的任務過程中與頁面互動,瀏覽器必須等待任務完成才能響應。
如果主線程處於阻塞狀態的時間超過 50 毫秒,用戶很可能會註意到延遲,並認為網頁運行緩慢或損壞。
2. 良好的 TBT 是多少時間?
網站的 TBT
應低於 200 毫秒。
TBT 時間(以毫秒為單位) | 顏色編碼 |
---|---|
0 - 200 | 綠色(快速) |
200-600 | 橙色(中等) |
600 多個 | 紅色(慢) |
3. 如何提高 TBT
-
將所有工作拆分為運行時間不超過 50 毫秒的代碼塊,併在合適的位置和時間運行這些代碼塊。
-
降低第三方代碼的影響
-
縮短
JavaScript
執行時間 -
去除不必要的
JS
載入、解析、執行 -
儘量減少主線程工作
-
儘量減少請求數量,減少傳輸大小
六、 CLS(Cumulative Layout Shift)
1. 什麼是 CLS
CLS
:從頁面開始載入到其生命周期狀態更改為隱藏期間發生的所有意外佈局偏移的累計得分。
每當可見元素的位置從渲染的幀更改為下一幀時,都會發生佈局偏移。
1.1. 什麼是佈局偏移
佈局偏移由 Layout Instability API
定義。
只要視窗內可見的元素在兩幀之間更改起始位置,該 API
就會報告 layout-shift
。此類元素被視為不穩定元素。
1.2. CLS
當資源以非同步方式載入或 DOM
元素被動態添加到頁面的現有內容之前,頁面內容通常會發生意外移動。
佈局偏移的原因可能包括尺寸未知的圖片或視頻、呈現的字體大於或小於其初始後備值,或者第三方廣告或微件會自行調整大小。
由於網站在開發過程中的運行情況與其用戶的體驗之間的差異,會使此問題變得更糟。例如:
-
個性化內容或第三方內容在開發和生產環境中的行為通常有所不同。
-
測試圖片通常已存在於開發者的瀏覽器緩存中,但為最終用戶載入所需時間更長。
-
在本地運行的
API
調用速度通常非常快,以至於開發過程中出現明顯的延遲,在生產環境中可能就會出現嚴重的延遲。
2. 頁面生命周期
3. 良好的 CLS 是多少?
為了提供良好的用戶體驗,網站應努力使 CLS 得分不超過 0.1。
4. 如何衡量 CLS
-
Chrome
用戶體驗報告
5. JS 中衡量 CLS
5.1. 簡單示例
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
console.log('Layout shift:', entry);
}
}).observe({type: 'layout-shift', buffered: true});
5.2. 指標與 API 的區別
-
如果網頁是在後臺載入的,或者在瀏覽器繪製任何內容之前在後臺播放,則系統不應報告任何
CLS
值。 -
如果某個網頁從往返緩存中恢復,其
CLS
值應重置為零,因為用戶此次體驗是一次不同的網頁訪問。 -
該
API
不會針對iframe
中發生的偏移報告layout-shift
,但該指標會報告這些變化,因為它們會影響網頁的用戶體驗。
5.3. 使用 web-vitalsJavaScript 庫衡量 CLS
可以使用 web-vitalsJavaScript
庫來衡量 CLS
import {onCLS} from 'web-vitals';
onCLS(console.log);
onCLS
源碼
6. 如何改善 CLS?
-
改善沒有尺寸的圖片
-
給嵌入內容的延遲載入預留空間
-
動畫:儘量使用
transform
平移動畫、縮放、旋轉/傾斜元素 -
網路字體優化
七、TTFB(Time to First Byte)
1. 什麼是 TTFB?
TTFB
:網路使用資源的第一個位元組響應用戶請求所需的時間。
TTFB
是以下請求階段的總和:
-
重定向時間
-
Service Worker
啟動時間(如果適用) -
DNS
查找 -
連接和
TLS
協商 -
請求,直到響應的第一個位元組到達
縮短連接設置時間和後端的延遲時間有助於降低 TTFB
。
2. 良好的 TTFB 是多少時間?
大多數網站都應儘量將 TTFB
控制在 0.8 秒以內。
3. 如何衡量 TTFB?
Chrome
用戶體驗報告web-vitalsJavaScript
庫WebPageTest
PerformanceObserver
方法
4. JS 衡量 TTFB
4.1. 簡單示例
new PerformanceObserver((entryList) => {
const [pageNav] = entryList.getEntriesByType('navigation');
console.log(`TTFB: ${pageNav.responseStart}`);
}).observe({
type: 'navigation',
buffered: true
});
4.2. 使用 web-vitalsJavaScript 庫衡量 TTFB
使用 web-vitalsJavaScript
庫也可以在瀏覽器中以較低的複雜性測量 TTFB
import {onTTFB} from 'web-vitals';
onTTFB(console.log);
onTTFB
源碼
5. 如何優化 TTFB?
-
具體的項目平臺
-
托管服務商
-
CDN
-
儘可能的使用緩存
-
避免多次重定向
-
使用
service worker
八、FID(First Input Delay)
1. 什麼是 FID?
FID
:從用戶首次與網頁互動到瀏覽器實際能夠開始處理事件處理腳本以響應相應互動的時間。
2. 良好的 FID 是多少時間?
為了提供良好的用戶體驗,網站應努力將 FID
控制在 100 毫秒以內
3. 如何衡量 FID?
FID
指標只能在實際操作衡量,因為它需要真實用戶的網頁互動
-
Chrome
用戶體驗報告 -
PageSpeed Insights
-
web-vitals JavaScript
庫 -
PerformanceObserver
4. 衡量 JS 中的 FID
4.1. 簡單示例
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});
4.2. 使用 web-vitals JavaScript 庫來衡量 FID
import {onFID} from 'web-vitals';
onFID(console.log);
onFID
源碼
5. 如何優化 FID?
-
拆分長任務
-
使用
web worker
-
縮短
JS
執行時間 -
減少多餘的
JS
-
針對具體的情況優化頁面
九、總結
- 本文整體的概括了以用戶為中心的性能衡量指標
- 也對每個指標進行了具體的描述和提出優化方案
- 希望對大家有幫助