如何有效度量前端效能

Kilmer發表於2023-02-10

目標:

  • 從使用者角度明確前端 Web、H5 效能測試需要重點關注的內容;
  • 根據關注內容明確效能測試過程中的效能評判指標和建議的閾值範圍;
  • 整理效能測試過程中各效能評價指標的收集方法;
  • 明確效能測試完畢後的測試結果展現形式;

質量模型:

使用者在訪問網頁時,網頁的效能好壞給使用者帶來了什麼,或者說使用者需要的高效能是什麼樣的,又或者說是使用者能感知到的效能是什麼?

# 使用者關注的內容 意義
1 是否正在發生? 當我輸入 URL 並回車時,導航到底有沒有發生呢?背後的伺服器是不是有響應呢?
2 是否有用? 我訪問頁面時,頁面是否快速展現了使用者最關注的內容或者是展現了產品最需要了解的內容?
3 是否可用? 當頁面第一次展現出可互動的元素時,使用者的使用是否是有效的?
4 是否令人愉悅的? 使用者與頁面的互動是否流程、自然?不會出現延遲和卡頓?

根據使用者感知的效能,我們可以初步確認前端 Web,H5 效能測試的維度、方向是以下內容:

# 維度 含義 使用者關注的內容
1 感知加速度(Perceived load speed) 頁面在螢幕上載入並渲染出所有視覺元素的速度 是否正在發生?
是否有用?
2 載入響應度(Load responsiveness ) 為了使元件對使用者互動作出快速響應,頁面載入和執行任何所需 JavaScript 程式碼的速度。 是否可用?
3 執行響應度(Runtime responsiveness) 頁面在載入後,對使用者互動的響應速度 是否令人愉悅?
4 視覺穩定性(Visual stability) 頁面上的元素是否會出現讓使用者感到意外的偏移,並對使用者互動造成潛在的干擾? 是否有用?
是否可用?
是否令人愉悅?
5 平滑度(Smoothness) 過渡和動畫在頁面狀態切換的過程中是否具有穩定的幀速率和順滑的流動性? 是否可用?
是否令人愉悅?

根據使用者對效能的感知和效能的測試維度,我們可以確認前端 Web、H5 效能測試的重要指標:

# 指標 含義 優先順序 測試維度
1 FCP First Contentful Panit:首次內容繪製

測量頁面從開始載入到頁面內容的任何部分在螢幕上完成渲染的時間。
P0 感知加速度
2 LCP Largest Contentful Paint:首次最大內容繪製

測量頁面從開始載入到最大文字塊或影像元素在螢幕上完成渲染的時間
P0 感知加速度
3 FID First Input Delay:首次輸入延時

測量從使用者第一次與您的網站互動(例如當他們單擊連結、點按按鈕或使用由 JavaScript 驅動的自定義控制元件)直到瀏覽器實際能夠對互動做出響應所經過的時間。
P3 載入響應度
4 TTI Time To Interactive:可互動時間

測量頁面從開始載入到視覺上完成渲染、初始指令碼(如果有的話)完成載入,並能夠快速、可靠地響應使用者輸入所需的時間。
P1 載入響應度、執行響應度
5 TBT Total Blocking Time 總阻塞時間

測量 FCP 與 TTI 之間的總時間,這期間,主執行緒被阻塞的時間過長,無法作出輸入響應。
P1 載入響應度、執行響應度
6 CLS Cumulative Layout Shift 累積佈局偏移

測量頁面在開始載入和其生命週期狀態變為隱藏期間發生的所有意外佈局偏移的累積分數。
P2 視覺穩定性、平滑度

在前端 Web、H5 的效能測試過程中,只感覺效能指標進行測試時不夠的,還需要確保功能的準確性和相容性

# 指標 含義 測試維度
1 AF Accurate Function
功能準確

測量頁面全部載入完成後,當前頁面的展現和互動功能是否符合產品設計和互動邏輯
2 CF Compatible Function
功能相容

測量同一個頁面在不同環境中(例如:網路環境,軟體環境、硬體環境)中的功能、效能表現

綜上所述,我們收斂出前端效能測試的質量模型

指標闡述和使用

FCP:

什麼是 FCP?

首次內容繪製 (FCP) 是測量感知載入速度的一個以使用者為中心的重要指標,因為該項指標會在使用者首次在螢幕上看到任何內容時,在頁面載入時間軸中標記出相應的點,迅捷的 FCP 有助於讓使用者確信某些事情正在進行。

測量什麼?

測量頁面從開始載入到頁面內容的任何部分在螢幕上完成渲染的時間。

建議指標閾值

JS 程式碼提取

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntriesByName('first-contentful-paint')) {
    console.log('FCP candidate:', entry.startTime, entry);
  }
}).observe({type: 'paint', buffered: true});

更多內容:

https://web.dev/fcp/

LCP:

什麼是 LCP?

最大內容繪製 (LCP) 是測量感知載入速度的一個以使用者為中心的重要指標,因為該項指標會在頁面的主要內容基本載入完成時,在頁面載入時間軸中標記出相應的點,迅捷的 LCP 有助於讓使用者確信頁面是有效的。

測量什麼?

測量頁面首次開始載入的時間點來報告可視區域內可見的最大影像或文字塊完成渲染的相對時間。

建議指標閾值

JS 程式碼提取

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntriesByName('first-contentful-paint')) {
    console.log('FCP candidate:', entry.startTime, entry);
  }
}).observe({type: 'paint', buffered: true});

更多內容:

https://web.dev/lcp/

FID:

什麼是 FID?

首次輸入延遲 (FID) 是測量載入響應度的一個以使用者為中心的重要指標,因為該項指標將使用者嘗試與無響應頁面進行互動時的體驗進行了量化,低 FID 有助於讓使用者確信頁面是有效的。

測量什麼?

測量從使用者第一次與頁面互動(例如當他們單擊連結、點按按鈕或使用由 JavaScript 驅動的自定義控制元件)直到瀏覽器對互動作出響應,並實際能夠開始處理事件處理程式所經過的時間。

A 時間點:頁面已經載入出了可互動的元素;

B 時間點:可互動的元素背後的 JS 程式碼開始在主執行緒中進行處理;

C 時間點:使用者與可互動的元素進行互動;

D 時間點:可互動元素背後的 JS 程式碼處理完成;

所以當使用者在時間點 C 的時候與元素進行互動時,並不能第一時間得到互動的反饋,需要等到 D 時間後才會得到互動的反饋,D-C = FID


在整個頁面的載入渲染過程中,讓使用者第一時間發現"立即搶購"按鈕併產生互動(點選時),便產生了 FID 的時間。

建議指標閾值

JS 程式碼提取

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});

更多內容:

https://web.dev/fcp/

TTI:

什麼是 TTI?

測量頁面從開始載入到視覺上完成渲染、初始指令碼(如果有的話)完成載入,並能夠快速、可靠地響應使用者輸入所需的時間。

測量什麼?

測量頁面從開始載入到主要子資源完成渲染,並能夠快速、可靠地響應使用者輸入所需的時間。

  1. 沿時間軸正向搜尋時長至少為 5 秒的安靜視窗。(安靜視窗的定義:沒有長任務(大於 50 毫秒)且不超過兩個正在處理的網路 GET 請求。)
  2. 沿安靜視窗的開始時間在時間軸上反向查詢最近一個長任務的結束時間點,即為 TTI。如果從 FCP 開始沒有大於 50ms 的長任務,TTI 則與 FCP 值相同。
  3. 圖例 1:
    1. T1 時間範圍內,存在 LongTask 且網路請求>2
    2. T2 時間範圍內,不存在 LongTask 但網路請求>2
    3. T3 時間範圍內 (持續 5 秒),不存在 LongTask 且網路請求<=2,因此我們認為 T3 時間內整個 UI 呈現的安靜視窗 ## 建議指標閾值 閾值的計算為開始載入到 TTI 出現的時長

更多內容:

https://web.dev/fcp/

TBT:

什麼是 TBT?

測量 FCP 與 TTI 之間的總時間,這期間,主執行緒被阻塞的時間過長,無法作出輸入響應。

測量什麼?

總阻塞時間 (TBT) 指標測量 FCP 與 TTI 之間的總阻塞時間,這期間,主執行緒被阻塞的時間過長,無法作出輸入響應。

TBT 是 TTI 的一個出色的配套指標,因為 TBT 有助於量化在頁面互動性變為可靠前,不可互動程度的嚴重性

瀏覽器頁面載入主執行緒中存在 5 個任務其中 3 個超過 50ms

雖然在主執行緒上執行任務的總時間為 560 毫秒,但其中只有 345 毫秒被視為阻塞時間。
T1 = TTI-FCP
TBT = T1 範圍內的 long task 時間總和-TI 範圍內的 long task 個數 *50ms


建議指標閾值

為了提供良好的使用者體驗,網站在普通移動硬體上進行測試時,應該努力將總阻塞時間控制在 300 毫秒以內。

更多內容:

https://web.dev/fcp/

CLS:

什麼是 CLS?

佈局偏移示例

測量什麼?

測量整個頁面生命週期內發生的所有意外佈局偏移中最大一連串的佈局偏移分數。

只要可視區域中可見元素的起始位置在兩幀之間發生了變更,這樣的元素認定為不穩定元素。

只有當元素的起始位置發生變更時才算作佈局偏移,新元素新增到 DOM 中或者改變元素的大小則不算佈局偏移。

影響分數:

第一幀中文字元素佔比 50%,在第二幀中文字元素其實未知下移 20%,文字元素的總可佔比變為 70%

距離分數:

距離分數指的是任何不穩定元素在一幀中位移的最大距離(水平或垂直)除以可視區域的最大尺寸維度(寬度或高度,以較大者為準)。

第二幀中位移距離在高度中佔比 20%

佈局偏移分數=影響分數 0.7* 距離分數 0.2 = 0.14

建議指標閾值

JS 程式碼提取

let clsValue = 0;
let clsEntries = [];

let sessionValue = 0;
let sessionEntries = [];

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    // 只將不帶有最近使用者輸入標誌的佈局偏移計算在內。
    if (!entry.hadRecentInput) {
      const firstSessionEntry = sessionEntries[0];
      const lastSessionEntry = sessionEntries[sessionEntries.length - 1];

      // 如果條目與上一條目的相隔時間小於 1 秒且
      // 與會話中第一個條目的相隔時間小於 5 秒,那麼將條目
      // 包含在當前會話中。否則,開始一個新會話。
      if (sessionValue &&
          entry.startTime - lastSessionEntry.startTime < 1000 &&
          entry.startTime - firstSessionEntry.startTime < 5000) {
        sessionValue += entry.value;
        sessionEntries.push(entry);
      } else {
        sessionValue = entry.value;
        sessionEntries = [entry];
      }

      // 如果當前會話值大於當前 CLS 值,
      // 那麼更新 CLS 及其相關條目。
      if (sessionValue > clsValue) {
        clsValue = sessionValue;
        clsEntries = sessionEntries;

        // 將更新值(及其條目)記錄在控制檯中。
        console.log('CLS:', clsValue, clsEntries)
      }
    }
  }
}).observe({type: 'layout-shift', buffered: true});


可以使用燈臺工具測試 CLS

更多內容:

https://web.dev/fcp/

測試環境:

環境 內容
網路 4g,5g,wifi
系統 android,iOS
快取 首開,二開
狀態 登陸,未登入
平臺 微信、小程式、瀏覽器

測試流程:

效能專項

對售賣流程中的某環節進行效能專項人工測試,各環境場景下各前端效能指標提取!

注意,我們建議:

  1. 新的核心的重要的且對前端效能有明確要求的業務出現時進行效能專項測試。而不是上線一段時候後再找時間補足效能專項測試。
  2. 效能專項會面臨一個問題是,根據任務排期和上線時間點的要求,專項測試的進入會對上線時間點產生衝擊,因為新頁面的上線從原來的功能測試->功能測試 + 效能專項。 #### 效能監控

對核心的重要的前端業務的某環節進行持續、週期效能提取,分析,報告。

注意,我們建議:

  1. 效能專項測試需要同步開啟效能監控(因為只有核心重要且有效能要求的前端業務才會做效能專項測試)
  2. 不建議直接在頁面中追加效能埋點直接進行效能監控。(因為效能埋點本身也是需要進行驗證的,如果效能埋點存在問題,那麼效能監控就沒有意義。)

效能專項流程

需求評審階段

  1. QA 需要判斷出是否需要做效能專項測試。如果需要和產品確認效能的要求。

    開發設計階段

  2. QA 需要將產品的效能要求翻譯成具體的效能指標並和開發確認。

  3. QA 與開發確認效能埋點指標範圍、上報資訊、埋點可提取性。

    測試設計階段

  4. QA 需要梳理當前效能專項測試對應的場景,工具、方法,裝置,報告。

    測試評審階段

  5. QA 明確已經確認的效能專項指標、場景、工具、方法、裝置、報告的有效性。

    測試階段

  6. QA 進行效能專項指標的提取、彙總。

  7. QA 測試過程中發現效能問題時,需要及時反饋、終止效能測試,待效能問題修復後繼續進行測試。

  8. QA 對效能監控依賴的效能埋點的有效性進行確認。

    效能監控流程

效能監控依賴的效能埋點發生新增或變化時,不需要進行效能專項測試,需要做到的是在測試階段功能測試後確認效能埋點的有效性。

效能監控≠效能專項測試

效能監控

對效能埋點的期望:

我們希望支撐效能監控的效能埋點能夠體現出以下資訊:

1、頁面名稱

2、業務流程名稱

3、頁面版本

4、環境:網路、平臺、系統、是否發生登陸等

透過以上資訊在效能監控中反應出特定流程下特定頁面的特定版本的各環境場景的效能表現。

相關文章