Skip to content

怎麼量 Core Web Vitals?實驗室數據與真實使用者數據

指標量測:實驗室數據與真實使用者數據

同一個 核心指標 有兩種來源,用途完全不同。搞混它們是效能優化最常見的挫折來源,「我明明改好了,數據怎麼沒動」。

兩種數據的分工

實驗室數據真實使用者數據
英文Lab DataField Data / RUM
來源在固定條件下模擬一次載入真實造訪的實際紀錄
工具Lighthouse 、DevToolsCrUX、Search Console 、自埋量測
反映速度立刻有延遲
涵蓋範圍一次載入所有裝置與網路
取值方式那一次的結果第 75 百分位
用途除錯驗收與評分

一句話記住

用實驗室數據找出是哪個資源的問題,用真實數據確認真的改善了。

為什麼兩邊數字會差很多

這不是哪一邊錯了

差異來源說明
裝置您的電腦比多數使用者的手機快得多
網路本機或機房的網路比行動網路快
快取狀態實驗室通常是全新造訪,真實使用者可能有快取
使用者行為INP 需要真的有人互動才量得到
取值方式實驗室是單次,真實數據取第 75 百分位

所以 Lighthouse 拿到 95 分而 Search Console 顯示「不佳」是完全正常的,後者才是評分依據

CrUX 與 28 天觀察窗

Chrome 使用者體驗報告(CrUX)是官方真實數據的來源。它有兩個特性要知道:

28 天滾動觀察窗

CrUX 的數據是 過去 28 天 的彙總。所以:

  • 改善上線後,數據要花將近一個月才完整反映。
  • 中間的過渡期會看到新舊資料混在一起,數字慢慢移動。
  • 不要因為改完當天數據沒動就以為沒效。

流量太少查不到數據

CrUX 需要足夠的造訪量才會提供某個網址的數據。小網站常遇到「查不到這個頁面」的情況。

退路有兩個:看同網域的整體數據(origin-level),或 自己埋設量測

查真實數據的三個地方

工具粒度適合
Search Console 的核心指標報告網址群組找出有問題的頁面類型
PageSpeed Insights單一網址同時看實驗室與真實數據
CrUX 的公開資料集網域或網址自己做趨勢分析

Search Console 會把相似的頁面歸成群組

它不會逐一列出每個網址,而是把版型相似的頁面歸成一組(例如:所有商品頁)。這其實很有用,問題通常是版型層面的,修一個模板就修好一整組。

自己埋設量測

官方數據有延遲、以群組彙總,也不會告訴您 是哪個元素 造成問題。自己埋設可以補上這三點。

用 web-vitals 套件

bash
npm install web-vitals
js
import { onLCP, onINP, onCLS } from 'web-vitals';

function send(metric) {
  // 用 sendBeacon 確保頁面關閉時也能送出
  const body = JSON.stringify({
    name: metric.name,
    value: metric.value,
    rating: metric.rating, // good / needs-improvement / poor
    path: location.pathname,
    // 造成問題的元素,這是官方數據給不了的
    target: metric.attribution?.element ?? null,
  });

  navigator.sendBeacon?.('/api/vitals', body) ??
    fetch('/api/vitals', { body, method: 'POST', keepalive: true });
}

onLCP(send);
onINP(send);
onCLS(send);

用 attribution 版本拿到具體元素

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

這個進階版會在 metric.attribution 裡附上:LCP 是哪個元素、INP 是哪次互動、CLS 是哪些元素在偏移,這是排查時最有價值的資訊

不裝套件的做法

三個指標都可以用 PerformanceObserver 自己觀察:

js
// LCP:取使用者互動前的最後一筆
new PerformanceObserver((list) => {
  const entries = list.getEntries();
  const last = entries[entries.length - 1];
  console.log('LCP:', last.startTime, last.element);
}).observe({ type: 'largest-contentful-paint', buffered: true });

// CLS:累加非使用者操作造成的位移
let cls = 0;
new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (!entry.hadRecentInput) {
      cls += entry.value;
      console.log(
        '累積 CLS:',
        cls,
        entry.sources?.map((s) => s.node),
      );
    }
  }
}).observe({ type: 'layout-shift', buffered: true });

// 互動延遲:記錄超過門檻的互動
new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (entry.interactionId) {
      console.log('互動延遲:', entry.duration, entry.name, entry.target);
    }
  }
}).observe({ type: 'event', buffered: true, durationThreshold: 40 });

自己算 CLS 與 INP 有細節要處理

CLS 的正式定義是「工作階段窗口」的最大值,不是單純累加;INP 是所有互動中接近最差的那一次,而非最後一次。

要精確的話用 web-vitals 套件,它已經處理好這些規則。上面的程式碼適合快速除錯,不適合當正式的量測。

送去哪裡

目的地適合
自家後端 API要完全掌控資料、做自訂分析
分析工具的自訂事件已經在用分析工具
專門的 RUM 服務不想自己維護儲存與儀表板

sendBeacon 而不是 fetch 的理由:頁面關閉時 fetch 可能被中斷,sendBeacon 會由瀏覽器在背景送完。

本機除錯的正確設定

本機不節流測不出真實情況

您的電腦處理器太快,一個在中階手機上 300 毫秒的長任務,在本機可能只有 30 毫秒。INP 的問題在本機幾乎測不出來。

開 DevTools 之後設定這兩項:

設定位置建議值
CPU 節流Performance 面板的齒輪4x 或 6x slowdown
網路節流Network 面板的 ThrottlingSlow 4G

再搭配 Rendering 面板的這幾個選項:

選項用途
Layout Shift Regions位移的區域會閃藍色,找 CLS 最快
Paint flashing重繪的區域會閃綠色
Frame Rendering Stats即時的幀率與 GPU 記憶體

兩邊不一致時怎麼判讀

症狀通常的原因怎麼做
實驗室好、真實差本機裝置與網路太好開節流重測,並看真實數據細分哪種裝置差
實驗室差、真實好多數使用者有快取,或測到了異常的一次多跑幾次取趨勢
改完真實數據沒動28 天觀察窗還沒反映等,或看自埋量測的即時數據
只有行動裝置差中低階手機的 CPU 與網路開 CPU 節流專門處理 INP
分數每次都不同實驗室數據本來就有浮動看多次結果的中位數,不要用單次下結論

建立一個可持續的流程

不要只在「感覺變慢」時才量

時機做什麼
每次提交程式碼Lighthouse CI 設分數門檻擋退步
每週看自埋量測的趨勢
每月看 Search Console 的核心指標報告
改版前後記下基準值,改版後比對

自埋量測的資料建議至少存這幾個維度,才能細分問題:

js
{
  name: 'LCP',
  value: 2840,
  rating: 'needs-improvement',
  path: '/seo/core-web-vitals',
  target: 'img.banner',          // 哪個元素
  deviceType: 'mobile',          // 裝置類型
  connection: '4g',              // 網路類型
  timestamp: 1757000000000,
}

這個站的做法

這個站目前 沒有埋設 RUM,只在正式機載入 GA4:

js
// 僅正式機設定 VITE_GA_ID,留空則不載入
...(gaId
  ? [
      ['script', { async: '', src: `https://www.googletagmanager.com/gtag/js?id=${gaId}` }],
      ['script', {}, `window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${gaId}');`],
    ]
  : []),

靜態站的效能問題比較單純

沒有 SSR、沒有網頁字型、橫幅是幾 KB 的 SVG,這種組合的核心指標通常不會有問題。真實數據看 Search Console 就夠了,不必額外埋設。

要不要自埋量測,取決於您有沒有需要細分的問題。 有網頁字型、有廣告、有大量互動的網站才真的需要。

檢查清單

項目標準
知道實驗室與真實數據的分工必備
用真實數據做評分依據必備
本機除錯時開了 CPU 與網路節流建議
改完之後有等真實數據反映必備
有在 Search Console 定期看核心指標報告建議
複雜網站有埋設 RUM建議
量測用 sendBeacon 送出建議
CI 有設效能門檻建議
不用單次分數下結論必備

常見問題

改完之後多久會反映在數據上?

實驗室數據立刻反映,真實使用者數據要等資料累積。CrUX 採 28 天滾動觀察窗,所以完整反映改善需要將近一個月。自己埋設的量測則可以即時看到。

為什麼稽核工具的分數和搜尋主控台的數據差很多?

資料來源不同。Lighthouse 是在固定條件下模擬一次載入,Search Console 呈現的是真實使用者在各種裝置與網路下的紀錄,取第 75 百分位。前者用來除錯,後者才是評分依據。

自己埋設量測有什麼好處?

三個:即時、可以細分到單一頁面與裝置類型、還能拿到造成問題的具體元素。CrUX 有延遲、以網址群組彙總,也不會告訴您是哪個元素造成偏移。

資料量太少會怎樣?

CrUX 需要足夠的造訪量才會提供數據,流量小的網站可能查不到自己的紀錄。這種情況只能靠自己埋設量測,或退而參考同網域的整體數據。

本機測不出真實情況怎麼辦?

開開發者工具的 CPU 與網路節流,模擬中階手機與行動網路。互動延遲 的問題尤其需要這樣做,因為本機的處理器太快,長任務在本機可能只有三十毫秒。

延伸閱讀

參考資料:web.dev:How to measure Core Web Vitals