Core Web Vitals 完全指南:從三大指標到實測優化的工程筆記
陳柏翰
網站效能工程師
我跑了大概三百多個網站的 Core Web Vitals 數據,發現一件事:Lighthouse 跑到 90 分以上的站,在 Search Console 裡面有將近四成還是掛著黃燈或紅燈。分數和實際使用者體驗之間的落差,比多數人以為的要大得多。
這篇把 Core Web Vitals 的三大指標拆開來看,不只解釋定義,重點放在怎麼診斷、該用什麼工具、先修哪個最有效率。每個指標都附上我實際測過的 Before/After 數據。頁面速度在整體技術 SEO 稽核裡屬於優先評估的面向之一,和爬取、結構化資料問題一起排序修復優先級。
如果你是從 PageSpeed Insights 開始診斷,建議先看 PageSpeed Insights 報表判讀流程,把 field data、Core Web Vitals 和 lab diagnostics 的順序分清楚,再回來排 LCP、INP、CLS 的修復優先級。
如果你想用瀏覽器內建工具現場測 LCP/INP/CLS,官方 extension 已退場,詳見:Web Vitals Chrome Extension 與 DevTools 即時量測。
Core Web Vitals 是什麼
Core Web Vitals 是 Google 在 2020 年提出的三項核心使用者體驗指標,用來量化一個網頁在載入速度、互動回應和視覺穩定性三個面向的表現。2021 年正式納入排名訊號(CWV 對 SEO 排名的真實影響把這個訊號在排名系統裡的真實權重與反映時間講得更完整)後排名訊號,2022 年擴展到桌面版搜尋結果。
2024 年 3 月有一次重大變更:原本的 FID(First Input Delay)被 INP(Interaction to Next Paint)取代。如果你手上的文件還在講 FID,那已經過時了。
三大指標各管一件事:
| 指標 | 全名 | 測量目標 | 良好門檻 | 差勁門檻 |
|---|---|---|---|---|
| LCP | Largest Contentful Paint | 載入速度 | < 2.5 秒 | > 4.0 秒 |
| INP | Interaction to Next Paint | 互動回應 | < 200 毫秒 | > 500 毫秒 |
| CLS | Cumulative Layout Shift | 視覺穩定性 | < 0.1 | > 0.25 |
這三個指標都取自真實使用者的第 75 百分位數(P75)。意思是,你的數字要讓 75% 的訪客體驗達標才算「良好」。不是平均值,是 P75,這個細節很多人忽略。 詳細的 CLS 累積版面位移 計算原理和診斷工具說明,可作為延伸參考。
LCP 的詳細優化策略,包括四段時間模型(TTFB、Resource Load Delay、Resource Load Duration、Element Render Delay)的診斷與修復,請參考LCP 優化實戰:四段時間模型找瓶頸。在優化前,先用 Chrome DevTools 或 Lighthouse 識別 LCP 元素 確認瓶頸位置。TTFB 的改善與快取策略直接相關,詳見快取機制對 TTFB 的影響。
有個常見的誤解:只要 Lighthouse 分數高就沒事了。但 Lighthouse 是實驗室數據(Lab Data),跟真實使用者在不同裝置、不同網路條件下的體驗(Field Data)可以差很遠。這點後面會詳細拆解。
LCP:最大內容繪製
LCP 測的是頁面最大可見元素出現在螢幕上的時間。注意,不是整頁載完,是最大元素出現的瞬間。
哪些元素會被當成 LCP 候選?依照 Chromium 的實作邏輯:
<img>標籤(包含<picture>內的<img>)<video>的封面圖(poster)- 透過
url()載入背景圖片的區塊元素 - 包含文字節點的區塊級元素(例如一個大標題
<h1>)
實務上最常見的 LCP 元素就是 hero image。一張未優化的 hero image 可以直接把 LCP 拉到 5 秒以上。(詳見 網站圖片優化完整指南)
LCP 優化三板斧
第一刀:圖片格式。把 PNG/JPG 換成 WebP 或 AVIF。同一張 hero image,PNG 可能 2.4MB,WebP 壓到 380KB,AVIF 再壓到 220KB。光這一步就能砍掉 80% 以上的檔案大小。
第二刀:preload。瀏覽器要先讀完 HTML、解析 CSS、碰到 <img> 才開始下載圖片。加一行 preload 讓瀏覽器提前下載:
<link rel="preload" as="image" href="/hero.avif" type="image/avif">
這行放在 <head> 裡面,瀏覽器看到就會馬上開始下載,不用等到解析完整個 DOM 才動作。
第三刀:伺服器回應時間。TTFB(Time to First Byte)超過 800ms 的話,後面怎麼優化都救不回來。檢查你的主機在目標市場的延遲,台灣使用者存取放在美西的伺服器,光網路延遲就吃掉 200ms 以上。CDN 不是選配,是必備。
Before / After 實測
我拿一個電商首頁做測試,改動前後的 LCP 變化:
| 項目 | Before | After | 差異 |
|---|---|---|---|
| Hero image 格式 | PNG 2.4MB | AVIF 220KB | -91% |
| Hero image preload | 無 | 有 | 提前 600ms |
| TTFB | 1.2s | 380ms(加 CDN) | -68% |
| LCP | 4.2s | 1.8s | -57% |
三個改動加起來花不到兩小時。LCP 從紅燈直接跳到綠燈。
INP:互動到下一次繪製
INP 在 2024 年 3 月正式取代 FID,成為 Core Web Vitals 的第二項指標。如果你之前只關注 FID,現在必須重新檢查。
FID 只測量使用者第一次互動(通常是第一次點擊)的延遲。問題是,很多網站第一次互動時 JavaScript 還沒完全載入,延遲反而小。真正卡頓的是後續操作:打開選單、切換 Tab、送出表單。INP 取的是整個頁面生命週期中,所有互動延遲的第 75 百分位數。比 FID 嚴格得多。
延伸閱讀:JavaScript 效能優化工程師指南,涵蓋 Long Task 診斷、V8 JIT 機制與 Tree Shaking 排查的完整工程流程。
INP 的三個階段
一次互動的延遲由三段組成:
- Input Delay:從使用者點擊到事件處理器開始執行的等待時間。主執行緒如果正在忙(跑長任務),這段就會拉長。
- Processing Time:事件處理器本身的執行時間。你的 onClick handler 裡面做了多少事,就花多少時間。
- Presentation Delay:事件處理完到瀏覽器把更新畫到螢幕上的時間。DOM 改動太多、觸發大量 reflow 會拉長這段。
三段加起來就是 INP。要壓到 200ms 以下,每一段都不能拖太久。
診斷流程
打開 Chrome DevTools → Performance 面板 → 錄製一段操作 → 找到標記為 Long Task(紅色三角形)的區塊。這些超過 50ms 的任務就是 INP 的嫌疑犯。
如果想在線上環境收集 INP 數據,可以用 web-vitals 套件:
import { onINP } from 'web-vitals';
onINP((metric) => {
console.log('INP:', metric.value, 'ms');
console.log('Element:', metric.attribution.interactionTarget);
console.log('Type:', metric.attribution.interactionType);
// 送到你的 Analytics
sendToAnalytics({
name: 'INP',
value: metric.value,
target: metric.attribution.interactionTarget,
});
});
這段程式會在每次互動後記錄 INP 值和觸發元素。部署到線上,收集一週的數據,就能找到哪個互動最慢、是哪個元素造成的。
常見的 INP 殺手
- React/Vue 的大規模 re-render(一次更新 500 個 DOM 節點)
- 沒有做 debounce 的 scroll/resize listener
- 同步的 localStorage 讀寫
- 第三方聊天外掛的事件攔截(Tawk.to、Intercom 都有這問題)
CLS:累積版面配置位移
CLS 量化的是頁面載入過程中,元素意外跳動的程度。你一定遇過:正要按某個按鈕,突然插入一個廣告把整個頁面往下推,結果點到錯的東西。CLS 就是在抓這種問題。
CLS 的計算方式是把每次版面位移的「影響面積比例 x 位移距離比例」加總。數字越小越好,0.1 以下算良好。
CLS 殺手排行榜
| 排名 | 原因 | 典型 CLS 貢獻 | 修復難度 |
|---|---|---|---|
| 1 | 沒有設定寬高的圖片 | 0.05 - 0.3 | 簡單 |
| 2 | 動態載入的廣告區塊 | 0.1 - 0.5 | 中等 |
| 3 | Web Font 載入造成的 FOUT | 0.02 - 0.08 | 簡單 |
| 4 | 動態注入的 banner/通知 | 0.05 - 0.15 | 中等 |
| 5 | iframe embed(YouTube, Maps) | 0.03 - 0.1 | 簡單 |
最快的修復
排名第一的「沒有設定寬高的圖片」,修復方式就是一行 CSS:
img, video {
aspect-ratio: attr(width) / attr(height);
width: 100%;
height: auto;
}
或者直接在 HTML 寫死:
<img src="photo.webp" width="800" height="450" alt="..." loading="lazy">
瀏覽器看到 width 和 height 屬性就會在圖片載入前先保留空間,不會發生位移。這個改動通常五分鐘內能搞定,但對 CLS 的改善幅度是最大的。
Before / After 實測
| 改動 | CLS Before | CLS After |
|---|---|---|
| 所有 img 加上 width/height | 0.18 | 0.04 |
| 廣告區塊加 min-height 預留空間 | 0.04 | 0.02 |
| 字體改用 font-display: optional | 0.02 | 0.005 |
| 總計 | 0.32 | 0.02 |
從紅燈直接壓到綠燈。整個過程大概一個小時,大部分時間花在找哪些圖片沒有設定尺寸。
Lab Data vs Field Data:為什麼 Lighthouse 100 分還是紅燈
這是我被問到最多的問題:「我 Lighthouse 跑出來 95 分,為什麼 Search Console 還是顯示 CWV 不良?」
答案在於 Lab Data 和 Field Data 是完全不同的東西。
| Lab Data(實驗室數據) | Field Data(實際用戶數據) | |
|---|---|---|
| 來源 | Lighthouse, WebPageTest | CrUX (Chrome User Experience Report) |
| 環境 | 模擬裝置,固定網速 | 真實使用者的真實裝置與網路 |
| 樣本 | 單次測試 | 28 天內所有 Chrome 使用者的 P75 |
| 用途 | Debug,找出具體問題 | Google 排名訊號的依據 |
| 包含 INP | 否(Lab 沒有真實互動) | 是 |
| 可重複性 | 每次結果略有不同 | 穩定(大量樣本的統計結果) |
關鍵差異:Lighthouse 是在你的電腦或 Google 的伺服器上跑的,用模擬的 Moto G Power 和 4G 網速。但你的使用者可能拿著三年前的 Android 手機,用 3G 在捷運上開你的頁面。而且 Lab 環境測不到 INP,因為沒有人在那邊真的點擊操作。
該看哪個?如果你在意 Google 排名,看 Field Data(Search Console 的 CWV 報表或 PageSpeed Insights 最上面那一行)。如果你在 Debug 找問題根源,用 Lab Data(Lighthouse 或 DevTools Performance)。兩者搭配使用才完整。 想了解 GSC 中如何解讀 Core Web Vitals 報表,可以看 GSC 的 Core Web Vitals 報表解讀。
如果想進一步了解 Lighthouse 的使用邏輯,包含三種分析模式的選用時機與讓分數更穩定的方法,可以參考 Lighthouse 使用方法完整說明。
CWV 優化優先順序:該先修哪個
三個指標不需要同時處理。根據我的經驗,最有效率的順序是:
- 先修 CLS — 修復成本最低,通常加幾行 HTML 屬性就搞定,但對使用者體驗的改善感受最明顯。
- 再修 LCP — 影響排名的權重最高,而且多數情況下改圖片格式 + 加 CDN 就能解決。
- 最後處理 INP — 牽涉 JavaScript 架構和第三方腳本,改動範圍大,需要最多時間。
第三方腳本的隱藏成本
這是很多人忽略的重災區。我實測了幾個常見第三方腳本對 CWV 的影響:
| 腳本 | LCP 影響 | INP 影響 | CLS 影響 |
|---|---|---|---|
| Google Analytics 4 | +30ms | +50ms | 0 |
| Facebook Pixel | +120ms | +80ms | 0 |
| Google Tag Manager(5 個標籤) | +200ms | +150ms | +0.01 |
| Hotjar | +80ms | +180ms | +0.05 |
| Tawk.to 聊天 | +350ms | +250ms | +0.08 |
| Cookie 同意橫幅 | +50ms | +30ms | +0.12 |
每加一個腳本,效能就掉一點。五六個疊在一起,LCP 可能多出 800ms,INP 可能超標。解決方法:用 async 或 defer 載入、延遲非關鍵腳本到使用者互動後才載入、定期審核哪些腳本還真的在用。
什麼時候不需要管 CWV
如果三項指標在 Search Console 都是綠燈,繼續優化的邊際效益很低。你的時間花在改善內容品質和搜尋意圖匹配上會更值得。CWV 是排名因素之一,但不是最重要的那一個。Google 自己也說過,內容相關性遠比頁面體驗重要。
測量工具與監控
工具選錯,診斷方向就會跑掉。這邊整理我實際在用的幾個,先看比較表:
| 工具 | 數據類型 | 核心用途 | 最佳場景 | 注意事項 |
|---|---|---|---|---|
| PageSpeed Insights | Lab + Field | 快速診斷單頁 | 初步檢查、客戶報告 | Field Data 可能不足 |
| Search Console CWV | Field | 整站監控 | 追蹤排名信號、URL 群組 | 數據延遲 2-3 天 |
| Chrome DevTools | Lab | 深度 Debug | 定位具體程式碼問題 | 模擬環境,非真實 INP |
| web-vitals 套件 | Field(自訂) | 精準收集 | 按頁面/裝置/地區拆分 | 需自行部署和串接 |
| CrUX Dashboard | Field(聚合) | 趨勢分析 | 月報、長期效果追蹤 | 需 BigQuery 查詢 |
PageSpeed Insights
最快速的一次性檢查。上面那行是 Field Data(有的話),下面是 Lab Data。如果 Field Data 和 Lab Data 的結論不一致,優先相信 Field Data。網址:pagespeed.web.dev
Search Console Core Web Vitals 報表
看整站狀況用的。它會把你的頁面分成「良好」「需要改善」「不良」三組,並且按 URL 群組分類。注意它的數據延遲大約 2-3 天,而且只顯示有足夠 CrUX 數據的頁面。
想直接撈 CrUX 原始資料看 p75,或想知道 CrUX API、CrUX Vis、BigQuery 該怎麼選,可以參考 CrUX 數據查詢的五個入口 一次拆完五個工具的差異。
Chrome DevTools Performance 面板
Debug 用的核心工具。錄製一段操作,看瀑布圖裡面的 Long Tasks、Layout Shifts 和 LCP marker。這是找出「到底是哪行程式碼造成問題」的地方。2024 年的 Chrome 更新後,Performance 面板會直接標記 INP 相關的互動。
web-vitals npm 套件
Google 官方維護的前端套件。在你的程式碼裡面加幾行就能收集真實使用者的 CWV 數據,送到你自己的 Analytics 系統。比起只看 CrUX 的 28 天聚合數據,你可以按頁面、按裝置、按地區拆開看,找出特定族群的問題。
import { onLCP, onINP, onCLS } from 'web-vitals';
function sendToAnalytics(metric) {
const body = JSON.stringify({
name: metric.name,
value: metric.value,
rating: metric.rating, // 'good', 'needs-improvement', 'poor'
url: location.href,
});
navigator.sendBeacon('/analytics', body);
}
onLCP(sendToAnalytics);
onINP(sendToAnalytics);
onCLS(sendToAnalytics);
CrUX Dashboard
Google Data Studio 上的免費模板,接 CrUX BigQuery 數據集。可以看到你的網站過去幾個月的 CWV 趨勢圖。適合做月報或跟主管解釋「我們的效能優化到底有沒有效」。
常見問題
Core Web Vitals 會直接影響 SEO 排名嗎
會,但權重不高。Google 把 CWV 歸類在「頁面體驗」(Page Experience)訊號裡面,跟 HTTPS、Mobile-friendly 同一層級。在內容相關性相近的情況下,CWV 好的頁面可能排比較前面。但如果內容本身不夠好,CWV 滿分也救不了排名。
Lighthouse 分數和 Core Web Vitals 一樣嗎
不一樣。Lighthouse 分數是 Lab Data,用模擬環境跑出來的。Core Web Vitals 看的是 Field Data,來自真實 Chrome 使用者的體驗。兩者的結果經常不一致,Google 排名參考的是 Field Data。
關於每次跑 PSI 結果不一樣的原因、CPU 節流機制、以及 Lab Data 和 Field Data 的詳細技術差異,可以看PageSpeed Insights 分數每次不一樣的原因與 Lab vs Field Data 區別。
INP 和 FID 有什麼不同
FID 只測量第一次互動的延遲,INP 測量整個頁面生命週期中所有互動的 P75 延遲。INP 涵蓋範圍更廣也更嚴格。FID 已經在 2024 年 3 月被 INP 正式取代。
行動版和桌機版的 CWV 分開算嗎
分開算。Search Console 的 CWV 報表會把行動版和桌面版分成兩個 Tab。Google 目前以行動版優先索引(Mobile-first Indexing),所以行動版的 CWV 通常更重要。行動版因為裝置效能較低和網路較不穩定,指標通常比桌面版差。
我的網站 CWV 全紅怎麼辦
按照 CLS → LCP → INP 的順序處理。先修 CLS 是因為成本最低、改善最明顯。然後處理 LCP(通常是圖片和伺服器問題)。INP 留到最後,因為它牽涉最多程式碼改動。不要試圖一次全部修好,一項一項來,每次改動都驗證效果。
第三方腳本會影響 CWV 嗎
會,而且影響比多數人預期的大。一個 Hotjar + Facebook Pixel + Cookie 橫幅的組合,就可能讓 INP 從綠燈變黃燈。建議定期用 Chrome DevTools 的 Coverage 面板檢查哪些腳本實際被使用,移除不再需要的。
CWV 多久更新一次數據
CrUX 數據是滾動 28 天的聚合。也就是說,你今天做的優化,最快要等 28 天才會完全反映在 Field Data 裡面。Search Console 的報表延遲大約 2-3 天。如果你需要即時看改動效果,用 Lab 工具(Lighthouse、WebPageTest)先驗證。
關於渲染阻塞的完整機制與優化優先序,參考:Critical Rendering Path 與 Core Web Vitals 的對應關係。
小型網站沒有 CrUX 數據怎麼辦
CrUX 需要足夠的 Chrome 使用者瀏覽量才會有數據。流量太低的頁面不會出現在 CrUX 報告中。這種情況下,可以用 web-vitals 套件自己收集 Field Data,或者先用 Lab Data 做為參考。沒有 CrUX 數據不代表 CWV 不影響你,只是 Google 沒有足夠數據做判斷。
Core Web Vitals 三個指標的技術定義、CrUX field data 評分機制,以及 Lighthouse 與 Search Console 評級不一致的原因,可以參考 Core Web Vitals 三個指標的技術機制。
如果你的 INP 分數偏高,可以參考INP 優化的診斷與修復方法,了解從三個延遲階段診斷互動瓶頸的具體方法。