偵錯欄位效能

瞭解如何使用偵錯資訊來歸因效能資料,協助您透過數據分析找出並修正使用者的實際問題

Google 提供兩種成效評估及偵錯工具:

  • 研究室工具:Lighthouse 等工具。Lighthouse 等工具會在模擬環境中載入網頁,而該環境會模仿各種條件 (例如網路速度緩慢和低階行動裝置)。
  • 現場工具:例如 Chrome 使用者體驗報告 (CrUX) 這類工具,是以 Chrome 的匯總實際使用者資料為基礎。(請注意,PageSpeed InsightsSearch Console 等工具回報的欄位資料來自 CrUX 資料。)

雖然現場工具可提供更準確的資料 (實際資料反映了實際使用者體驗的資料),但研究室工具通常更能協助您找出及修正問題。

CrUX 資料更能代表網頁的實際效能,但瞭解 CrUX 分數無法協助您找出改善效能的「方法」

另一方面,Lighthouse 也會找出問題,並提供具體的改善建議。不過,Lighthouse 只會針對網頁載入時發現的效能問題提供建議。但無法偵測僅因使用者互動而引發的問題 (例如網頁上的捲動或點擊按鈕)。

這意味著一個重要問題是:如何擷取 Core Web Vitals 指標的偵錯資訊,或實際使用者的其他效能指標?

本文將詳細說明可以使用哪些 API 來收集每個目前 Core Web Vitals 指標的其他偵錯資訊,並瞭解如何在現有的分析工具中擷取這類資料。

用於歸因和偵錯的 API

累計版面配置位移 (CLS)

在所有 Core Web Vitals 指標中,CLS 可能是在欄位中收集偵錯資訊最重要的指標。CLS 是整個網頁生命週期的評估依據,因此使用者與網頁的互動方式 (捲動距離、點擊的內容等) 可能會對是否有版面配置位移以及哪些元素位移產生重大影響。

請參考 PageSpeed Insights 提供的下列報告:

含有不同 CLS 值的 PageSpeed Insights 報表
PageSpeed Insights 會顯示欄位和研究室資料 (如果有的話,這些資料可能不同)

與研究室 (Lighthouse) 從研究室回報的 CLS 值 (Lighthouse) 與實際環境 CLS (CrUX 資料) 相差不遠,若您認為該頁面含有大量互動內容,而在 Lighthouse 中進行測試時可能沒有使用,那就很合理。

但即使您瞭解使用者互動會影響欄位資料,您還是需要知道頁面中哪些元素在第 75 個百分位數會經過轉變,導致 0.28 的分數達到 0.28。只要使用 LayoutShiftAttribution 介面,即可達成這項目標。

取得版面配置位移歸因

Layout Instability API 發出的每個 layout-shift 項目上,都會顯示 LayoutShiftAttribution 介面。

如需這兩個介面的詳細說明,請參閱「對版面配置位移進行偵錯」。就本文目的而言,您需要知道,開發人員能夠觀察頁面上發生的所有版面配置位移,以及哪些元素會位移。

以下程式碼範例會記錄每個版面配置位移以及移動的元素:

new PerformanceObserver((list) => {
  for (const {value, startTime, sources} of list.getEntries()) {
    // Log the shift amount and other entry info.
    console.log('Layout shift:', {value, startTime});
    if (sources) {
      for (const {node, curRect, prevRect} of sources) {
        // Log the elements that shifted.
        console.log('  Shift source:', node, {curRect, prevRect});
      }
    }
  }
}).observe({type: 'layout-shift', buffered: true});

在每次發生單一版面配置位移時,測量資料並傳送至分析工具可能並不實用;不過,您可以透過監控所有位移追蹤最差的位移,只回報這些位移的相關資訊。

目標並非識別及修正每位使用者發生的每個版面配置位移情形;我們的目標是找出影響最大使用者人數的變化,從而在第 75 個百分位數分配最多頁面 CLS。

此外,您不需要在每次有班次時計算最大的來源元素,只需要在將 CLS 值傳送至分析工具時進行此操作。

以下程式碼取得了對 CLS 有貢獻的 layout-shift 項目,並從最大偏移值傳回最大的來源元素:

function getCLSDebugTarget(entries) {
  const largestEntry = entries.reduce((a, b) => {
    return a && a.value > b.value ? a : b;
  });
  if (largestEntry && largestEntry.sources && largestEntry.sources.length) {
    const largestSource = largestEntry.sources.reduce((a, b) => {
      return a.node && a.previousRect.width * a.previousRect.height >
          b.previousRect.width * b.previousRect.height ? a : b;
    });
    if (largestSource) {
      return largestSource.node;
    }
  }
}

找出造成最大變動幅度最大的元素後,便可向數據分析工具回報該指標。

在特定頁面上,影響最多 CLS 的元素,可能會依使用者而異,但如果您在所有使用者中匯總這些元素,就可以產生一份變動性元素清單,影響最多使用者人數。

找出並修正這些元素出現變動的根本原因後,分析程式碼就會開始記錄變化幅度,因為網頁的「最差」轉變。最後,所有回報的變動幅度都會夠小,讓你的網頁遠離「良好」門檻

以下是與最大位移來源元素一起拍攝的其他中繼資料:

  • 出現最大變動的時間
  • 最大移位時的網址路徑 (適用於動態更新網址的網站,例如單頁面應用程式)。

最大內容繪製 (LCP)

如要對欄位中的 LCP 進行偵錯,您需要的主要資訊是該特定網頁載入的最大元素 (LCP 候選元素)。

請注意,LCP 候選元素和使用者各有不同,就算是完全相同的網頁,實際上也很常見。

問題的原因如下:

  • 使用者裝置的螢幕解析度各不相同,這會導致頁面版面配置不同,因而在可視區域中顯示不同的元素。
  • 使用者不一定會載入捲動至最頂端的網頁。連結通常會包含片段 ID,甚至是文字片段,因此網頁可能會在網頁上的任何捲動位置載入並顯示。
  • 內容會針對目前的使用者提供個人化內容,因此 LCP 候選元素可能會隨使用者而有極大差異。

這表示您無法假設哪個元素或元素組合會是特定網頁的最常見 LCP 候選元素。您必須根據實際使用者的行為進行評估。

找出 LCP 候選元素

如要在 JavaScript 中判斷 LCP 候選元素,您可以使用 Largest Contentful Paint API,也就是用來決定 LCP 時間值的同一個 API。

觀察 largest-contentful-paint 項目時,您可以透過查看最後一個項目的 element 屬性,判斷目前的 LCP 候選元素:

new PerformanceObserver((list) => {
  const entries = list.getEntries();
  const lastEntry = entries[entries.length - 1];

  console.log('LCP element:', lastEntry.element);
}).observe({type: 'largest-contentful-paint', buffered: true});

瞭解 LCP 候選元素後,即可將其連同指標值一併傳送至分析工具。和 CLS 一樣,這有助於您找出哪些元素最需要最佳化。

除了 LCP 候選元素以外,評估 LCP 子部分的時間也非常實用,有助於確定與網站相關的具體最佳化步驟。

與下一個顯示的內容互動 (INP)

在 INP 欄位中需要擷取的最重要資訊如下:

  1. 使用者與哪個元素互動
  2. 為什麼會有互動類型?
  3. 發生該互動的時間

互動速度緩慢的主因是主執行緒遭到封鎖,在 JavaScript 載入期間可能很常見。掌握網頁載入期間是否發生最慢的互動,有助於判斷修正問題的需要採取的行動。

INP 指標會將互動的完整延遲時間納入考量,包括執行任何已註冊的事件監聽器所需的時間,以及所有事件監聽器執行後繪製下一個影格所需的時間。這表示對於 INP 來說,瞭解哪些目標元素會導致互動速度緩慢,以及這些元素屬於何種互動類型。

下列程式碼會記錄 INP 項目的目標元素和時間。

function logINPDebugInfo(inpEntry) {
  console.log('INP target element:', inpEntry.target);
  console.log('INP interaction type:', inpEntry.name);
  console.log('INP time:', inpEntry.startTime);
}

請注意,這個程式碼並未展示如何判斷哪個 event 項目是 INP 項目,因為其邏輯較為複雜。不過,下一節將說明如何使用 web-vitals JavaScript 程式庫取得這項資訊。

搭配 Web-Vitals JavaScript 程式庫使用

前幾節提供了一些一般建議和程式碼範例,讓您擷取偵錯資訊並納入數據分析工具的資料中。

自第 3 版起,網頁 Vitals JavaScript 程式庫包含會顯示所有相關資訊的「歸因建構」,以及一些其他信號

以下程式碼範例說明如何設定其他包含偵錯字串的事件參數 (或自訂維度),有助於找出效能問題的根本原因。

import {onCLS, onINP, onLCP} from 'web-vitals/attribution';

function sendToGoogleAnalytics({name, value, id, attribution}) {
  const eventParams = {
    metric_value: value,
    metric_id: id,
  }

  switch (name) {
    case 'CLS':
      eventParams.debug_target = attribution.largestShiftTarget;
      break;
    case 'LCP':
      eventParams.debug_target = attribution.element;
      break;
    case 'INP':
      eventParams.debug_target = attribution.interactionTarget;
      break;
  }

  // Assumes the global `gtag()` function exists, see:
  // https://developers.google.com/analytics/devguides/collection/ga4
  gtag('event', name, eventParams);
}

onCLS(sendToGoogleAnalytics);
onLCP(sendToGoogleAnalytics);
onFID(sendToGoogleAnalytics);
onINP(sendToGoogleAnalytics);

雖然這段程式碼是 Google Analytics (分析) 特有的,但一般來說也應轉譯到其他分析工具。

此程式碼也顯示如何回報單一偵錯信號,但能夠針對個別指標收集和回報多個不同的信號會很有幫助。

舉例來說,如要對 INP 進行偵錯,建議您收集要互動的元素、互動類型、時間、loadState、互動階段等 (例如長動畫影格資料)。

web-vitals 歸因版本會顯示其他歸因資訊,如以下範例 INP 所示:

import {onCLS, onINP, onLCP} from 'web-vitals/attribution';

function sendToGoogleAnalytics({name, value, id, attribution}) {
  const eventParams = {
    metric_value: value,
    metric_id: id,
  }

  switch (name) {
    case 'INP':
      eventParams.debug_target = attribution.interactionTarget;
      eventParams.debug_type = attribution.interactionType;
      eventParams.debug_time = attribution.interactionTime;
      eventParams.debug_load_state = attribution.loadState;
      eventParams.debug_interaction_delay = Math.round(attribution.inputDelay);
      eventParams.debug_processing_duration = Math.round(attribution.processingDuration);
      eventParams.debug_presentation_delay =  Math.round(attribution.presentationDelay);
      break;

    // Additional metric logic...
  }

  // Assumes the global `gtag()` function exists, see:
  // https://developers.google.com/analytics/devguides/collection/ga4
  gtag('event', name, eventParams);
}

onCLS(sendToGoogleAnalytics);
onLCP(sendToGoogleAnalytics);
onFID(sendToGoogleAnalytics);
onINP(sendToGoogleAnalytics);

如需公開的偵錯信號完整清單,請參閱網頁 Vitals 歸因說明文件

製作資料報表並以視覺化方式呈現

開始收集偵錯資訊和指標值後,下一步就是匯總所有使用者的資料,以便開始搜尋模式和趨勢。

如前文所述,您不一定需要解決使用者遇到的每一個問題,建議您優先解決影響最多使用者的問題,而這些問題對於 Core Web Vitals 分數的影響最大。

如果是 GA4,請參閱如何使用 BigQuery 查詢資料並以視覺化方式呈現資料的專用文章。

摘要

希望本文已概述如何使用現有效能 API 和 web-vitals 程式庫取得偵錯資訊,以根據實際使用者造訪現場的造訪情況診斷效能。雖然本指南著重於說明 Core Web Vitals,但相關概念也適用於任何可透過 JavaScript 評估的效能指標。

如果您才剛開始評估效能,也已經是 Google Analytics (分析) 使用者,不妨考慮使用 Web Vitals 報表工具,因為這項工具已能回報 Core Web Vitals 指標的偵錯資訊。

如果您是分析服務供應商,且想要改善產品並為使用者提供更多偵錯資訊,請考慮本文所述的一些技巧,但不侷限於這裡介紹的想法。本文主要適用於所有數據分析工具,不過,各個分析工具或許 (也應該) 可能會 (也應該) 擷取並回報更多偵錯資訊。

最後,如果您認為 API 中缺少某些功能或資訊,導致您難以對這些指標進行偵錯,請將您的意見回饋傳送至 web-vitals-feedback@googlegroups.com