題幹與適用情境
某電商商品頁的行動裝置 28 天 field data 顯示:p75 LCP 為 4.1 秒、INP 為 320 毫秒、CLS 為 0.06。桌面端三個指標全部達標,而開發者在本機執行 Lighthouse 得到 LCP 1.8 秒、TBT 80 毫秒、CLS 0.01。請說明如何核對這組差異、定位 LCP 與 INP 的根因、安排修復順序,並證明上線後的改動真正改善了使用者體驗。
題目採用目前 Core Web Vitals 的良好門檻:分別統計行動裝置與桌面端的第 75 百分位,LCP 不超過 2.5 秒、INP 不超過 200 毫秒、CLS 不超過 0.1。題設數字是面試演算資料,不代表任何公司的真實頁面。目標不是背誦改善清單,而是把使用者分布、指標組成、瀏覽器工作和驗證方法連成一條可被推翻的診斷鏈路。
這道題適用於中高階前端、Web 效能與全端職缺。候選人既要了解網路瀑布、主執行緒和版面配置,也要知道 Lighthouse 的單次實驗室執行不能推翻真實使用者資料,TBT 也不等於 INP。
面試官考察重點
第一,能否先統一資料口徑。好的回答會確認 field data 來自單一 URL、URL 群組還是整個 origin,依行動裝置與桌面端、路由樣板、裝置等級、網路、地區和版本切分;普通回答看到本機 Lighthouse 變綠就宣告沒有問題。
第二,能否把三個指標對應到不同瓶頸。LCP 關心主要內容何時出現,INP 關心一次互動從輸入到下一幀的總延遲,CLS 關心非預期版面移動。它們共享部分主執行緒和渲染成本,但不能用「縮小 bundle」解釋所有問題。
第三,能否依組成時間定位根因。LCP 可以拆成 TTFB、資源載入延遲、資源載入時間和元素渲染延遲;一次互動的 INP 延遲可以拆成輸入延遲、處理時間和呈現延遲。修復必須指向占比異常的組成,不是從常見技巧中隨機挑選。
第四,能否正確使用 field 與 lab 工具。RUM 和 CrUX 說明真實使用者受到什麼影響,DevTools、Lighthouse 和可重現的受限裝置情境協助解釋原因。Lighthouse 沒有真實使用者互動時不能測量 INP,只能用 TBT 等實驗室訊號輔助排查。
第五,能否證明改善而不只展示部署。上線後需要依版本或灰度組比較同口徑 RUM 分布,檢查錯誤率和業務守護指標,再等待 28 天滾動 field data 逐步確認。單次快照、平均值下降或一台裝置變快都不能證明 p75 達標。
回答前需要釐清的問題
- field data 的粒度是什麼? URL、URL 群組和 origin 的結果可能不同。若 4.1 秒來自整個 origin,就不能直接認定商品頁是根因;若來自商品頁樣板,應繼續切分該樣板的造訪。
- 行動裝置樣本來自哪些裝置、網路和地區? 只有低階裝置或特定地區失敗時,重現情境與修復優先順序會不同。把行動裝置和桌面端合併會掩蓋問題。
- 指標從什麼時候開始變差? 與某個發布版本、第三方指令碼、圖片管線或流量組成變化對齊,可以縮小候選根因。28 天滾動值不會精確顯示某次發布的即時影響。
- LCP 元素和慢 INP 互動分別是什麼? Hero 圖片、標題文字和客戶端渲染容器的修復方式不同;加入購物車、規格選擇和搜尋輸入的主執行緒路徑也不同。
- 本機 Lighthouse 如何執行? 裝置、網路節流、快取、登入狀態、頁面資料和測試路徑必須接近慢速使用者。高效能筆電上的一次冷啟動無法代表行動裝置分布。
- 可以改動哪些層? 若團隊只能改前端,仍應量化 TTFB,但不能假裝能直接修復來源站;若 CDN、伺服器端渲染和圖片服務都在範圍內,方案可以涵蓋整條關鍵路徑。
- 怎樣定義發布成功? 本題要求行動裝置 p75 三項都達到良好門檻,同時守住錯誤率、轉換和無障礙;不能為了提前繪製 Hero 而交付錯誤圖片或阻塞關鍵互動。
30 秒回答架構
「我先確認 4.1 秒和 320 毫秒是行動裝置 URL 級還是 origin 級 field data,並依路由樣板、裝置、網路和發布版本切分。Lighthouse 的 TBT 不是 INP,所以本機結果不能否定真實使用者問題。接著用 RUM 找到實際 LCP 元素和最慢互動,再在相近裝置上錄製網路與 Performance trace。LCP 依 TTFB、資源發現、下載和渲染四段處理;INP 依輸入、事件處理和下一幀呈現三段處理。CLS 已是 0.06,我會保留回歸護欄而不優先投入。最後灰度上線,用同口徑 RUM 比較 p75 與守護指標,並等待 CrUX 的 28 天視窗確認。」
分步深入解答
第一步:先解釋 field 與 lab 為什麼可以同時正確
28 天 field data 彙整了真實使用者的裝置、網路、快取狀態、頁面生命週期和互動。題設的行動裝置 p75 LCP 4.1 秒表示約最慢四分之一的相關造訪處於 4.1 秒或更慢;它不是「一台典型手機耗時 4.1 秒」。桌面端達標表示問題可能集中在受限 CPU、行動網路、行動版樣板或行動使用者路徑。
本機 Lighthouse 是受控實驗。它能穩定重跑、查看瀑布和發現回歸,卻只有一組裝置與網路條件。Lighthouse 沒有使用者輸入時不能直接得到 INP,TBT 80 毫秒只是主執行緒阻塞的實驗室診斷訊號。頁面可能在啟動階段 TBT 很低,卻在使用者開啟規格選擇器後執行 300 毫秒工作;也可能實驗室 TBT 很高,但真實使用者很少在阻塞期間互動。
先在 PageSpeed Insights 或資料平台確認這是 URL、origin 還是 URL 群組資料,分別查看行動裝置與桌面端。再用第一方 RUM 依頁面樣板、裝置等級、有效連線類型、地區、導覽類型和應用程式版本切分。切分欄位要有足夠樣本且符合隱私邊界,不能為了定位效能收集完整查詢參數、輸入文字或使用者身分。
第二步:建立能定位而非只報分數的 RUM
最小採集可以使用 web-vitals 上報三個指標。以下程式碼在三語版本中保持一致:
import { onCLS, onINP, onLCP } from 'web-vitals';
function sendToAnalytics(metric) {
const body = JSON.stringify({
name: metric.name,
value: metric.value,
id: metric.id,
rating: metric.rating,
route: location.pathname,
});
(navigator.sendBeacon && navigator.sendBeacon('/rum', body)) ||
fetch('/rum', { body, method: 'POST', keepalive: true });
}
onCLS(sendToAnalytics);
onINP(sendToAnalytics);
onLCP(sendToAnalytics);範例為了易讀使用 location.pathname;正式環境應映射成低基數路由樣板,例如 /products/:id,並附上發布版本、裝置等級和必要的歸因欄位。禁止傳送查詢參數、DOM 文字或可識別使用者的資訊。metric.id 可協助區分一次頁面造訪中的指標事件,但伺服器端仍要定義重複上報與取樣規則。
只保存 name 與 value 仍不足以修復問題。LCP 需要元素與四段耗時,INP 需要互動目標和三段耗時,CLS 需要移動元素與發生階段。可以使用 attribution 版本或既有 RUM 產品補充這些欄位。彙整時對每次導覽的最終指標求百分位;不要先對各子項分別求 p75 再相加,因為不同百分位點可能來自不同造訪。
第三步:用四段耗時診斷 LCP
一筆具代表性的慢速行動裝置導覽顯示:TTFB 0.6 秒、資源載入延遲 1.5 秒、資源載入時間 0.9 秒、元素渲染延遲 1.3 秒,總 LCP 為 4.3 秒。這四項來自同一次導覽,因此可以相加;它們不是四個獨立 p75。
最大的兩個可疑段是資源載入延遲與渲染延遲。先查看 Hero 是否直到客戶端 JavaScript 執行後才插入,或是否錯誤使用延遲載入。若是圖片,讓 <img> 及 src/srcset 出現在初始 HTML,提供正確的 sizes,不要對首屏 LCP 圖片設定 lazy loading,並只給真正關鍵的資源較高 fetchpriority。如果資源只能從 CSS 發現,再評估精確 preload;不能替所有大圖加 preload,否則會爭搶頻寬。
資源下載完成後仍等待 1.3 秒,表示繼續壓縮圖片可能只把時間移到渲染延遲。應檢查大段同步 JavaScript、客戶端渲染門檻、阻塞樣式、字型和隱藏 Hero 的狀態。伺服器端輸出可見 Hero、縮小關鍵 CSS 和延後非關鍵 hydration 都可能有效,但必須用新 trace 驗證目標段真的縮短。TTFB 0.6 秒仍需監控;目前樣本的優先順序低於 1.5 秒與 1.3 秒的延遲,不表示它永遠不用改善。
第四步:用三段耗時診斷 INP
一筆具代表性的慢速「選擇規格」互動為 350 毫秒:輸入延遲 140 毫秒、事件處理 120 毫秒、呈現延遲 90 毫秒。三段來自同一互動,所以總和成立。field p75 INP 320 毫秒是另一項彙整統計,不能用這筆 trace 取代整體分布。
輸入延遲表示使用者操作時主執行緒已被其他工作占用。錄製從互動前開始的 Performance trace,尋找指令碼解析、第三方標籤、計時器或 hydration 造成的長工作;拆分可中斷工作,把非關鍵工作延後,並避免在頁面啟動階段集中執行。只縮短目前的點擊處理函式不會消除前面的 140 毫秒排隊。
處理時間對應事件回呼本身。先讓選中狀態或載入回饋進入下一幀,再執行庫存分析、推薦更新或日誌等非關鍵工作;移除重複計算,縮小狀態更新範圍。呈現延遲則要檢查大型 DOM 更新、強制同步版面配置和 layout thrashing,把 DOM 讀寫分組並減少這次互動必須重繪的區域。每次只改一個已測瓶頸,用同一路徑重測三段時間。
第五步:讓已經達標的 CLS 成為回歸護欄
CLS 0.06 已低於 0.1,目前不應壓過失敗的 LCP 和 INP。它仍需要守護,因為提前載入 Hero、替換圖片元件或增加互動回饋都可能引入新版面移動。圖片和影片提供 width、height 或穩定的 aspect-ratio,廣告、推薦和非同步內容事先保留空間,字型替換要控制尺寸差異。
實驗室 CLS 0.01 與 field CLS 0.06 的差異也有資訊量。預設 Lighthouse 主要涵蓋載入階段,而真實使用者可能在捲動、開啟元件或長時間停留期間遇到後載入移動。用 RUM 歸因和 DevTools Layout Shifts 軌道重現對應路徑。跨網域 iframe 內的版面移動可能出現在 CrUX 中,卻無法由頂層頁面的 Web API 完整歸因;遇到這種差異要同時檢查嵌入內容。
第六步:依證據安排改動與灰度發布
不要分別成立「圖片專案」和「JavaScript 專案」後平行改完所有內容。目前 trace 顯示,客戶端延遲發現 Hero 與主執行緒長工作可能同時推高 LCP 的資源/渲染延遲和 INP 的輸入延遲。第一批改動可以圍繞同一個假設:讓 Hero 在初始 HTML 可被發現,並延後首屏不需要的 JavaScript。如此改動小、因果清楚,也可能同時改善兩個失敗指標。
為每個改動寫出預期訊號:Hero 可發現性改動應降低 resource load delay;減少啟動長工作應降低 LCP render delay、INP input delay 與實驗室 TBT。若對應組成沒有變化,就不能把總分偶然波動歸功於該修復。圖片品質、錯誤率、頁面可用時間、轉換和無障礙作為守護指標,避免用效能數字掩蓋功能退化。
先對一部分流量灰度,並保留可比較的舊版本或同期基線。依路由、行動裝置和版本比較同一口徑的分布,同時確認流量組成沒有明顯偏移。發布與流量變化重疊時,前後時間比較只能說明相關,不能自動證明因果。
第七步:用三層證據關閉問題
第一層是提交前實驗室護欄:固定受限行動裝置設定、快取狀態和關鍵互動,記錄 LCP、TBT、CLS、資源瀑布與 Performance trace。它適合阻止明顯回歸,但不能取代真實 INP。
第二層是發布後的 RUM。檢查樣本量、取樣是否一致、指標事件是否去重,再比較行動裝置商品頁樣板的 p75 LCP、INP 和 CLS,以及各組成與守護指標。短期 RUM 可以快速發現方向,但資料不足時只能報告信心不足,不能宣告全量使用者已達標。
第三層是 CrUX 或 Search Console 的 28 天滾動確認。舊造訪會逐步退出視窗,所以指標不會在部署當天跳到新穩態。達標標準是行動裝置與桌面端分別在 p75 同時符合 LCP ≤ 2.5 秒、INP ≤ 200 毫秒、CLS ≤ 0.1;CLS 不能因修 LCP 而從 0.06 退化越線。記錄回滾門檻和所有未改善的細分群體,避免總量達標後遺留低階裝置問題。
高品質示範回答
「我不會用本機 Lighthouse 的綠色結果否定行動裝置 field data。先確認 4.1 秒來自商品詳情 URL、URL 群組還是 origin,並把行動裝置依裝置、網路、地區和發布版本切開。28 天 p75 是分布,不是一台裝置;Lighthouse 的 TBT 也不是 INP。
我會補齊 RUM 歸因,找到真實 LCP 元素和最慢互動,再用相近裝置錄製 trace。假設一筆慢導覽的 LCP 四段是 0.6、1.5、0.9 和 1.3 秒,我會先解決 1.5 秒的資源發現和 1.3 秒的渲染等待:讓 Hero 圖片出現在初始 HTML,取消首屏延遲載入,並減少擋住繪製的客戶端工作,不會先盲目壓縮已經下載完成的圖片。
對 INP,我會把慢互動拆成輸入延遲、處理和呈現。若是 140、120、90 毫秒,就先找出互動前占住主執行緒的啟動工作,再縮短事件回呼並減少這次更新的版面配置與繪製。CLS 0.06 已達標,只保留圖片尺寸和非同步內容占位等回歸護欄。
我會用小流量發布,每項改動都對應一個應下降的組成時間,以同口徑 RUM 比較版本與守護指標。實驗室效能預算用於提交前防回歸,RUM 用於快速判斷真實影響,CrUX 的 28 天視窗用於最終確認。只有行動裝置 p75 LCP、INP、CLS 同時達到 2.5 秒、200 毫秒和 0.1,而且錯誤率、轉換和無障礙沒有退化,我才會關閉問題。」
常見錯誤
- 本機 Lighthouse 達標就否定 field data → 兩者涵蓋的使用者、時間窗和互動不同 → 先統一 URL、裝置、網路、版本和指標口徑。
- 把 TBT 80 毫秒當成 INP 80 毫秒 → Lighthouse 沒有真實互動時無法測 INP → 用 field INP 定義影響,用 TBT 與互動 trace 輔助診斷。
- 只看全站平均值 → 平均值會掩蓋行動裝置尾端與特定樣板 → 依行動/桌面分開計算 p75,再切分有足夠樣本的群體。
- 看到 LCP 慢就先壓縮圖片 → 瓶頸可能是資源發現或渲染等待 → 先拆四段,再修改占比異常的部分。
- 替所有首屏資源加 preload 與高優先權 → 關鍵資源會互相爭搶頻寬 → 只提升已確認的 LCP 資源,並複查瀑布。
- 只改善點擊回呼 → 輸入延遲可能來自回呼前的長工作,呈現延遲可能來自版面配置 → 分別檢查輸入、處理和呈現三段。
- 優先把 CLS 從 0.06 降到 0.02 → 資源投入已達標指標,LCP 與 INP 仍失敗 → 保留 CLS 護欄,優先處理越線指標。
- 把四個子項的 p75 相加 → 各百分位點可能來自不同頁面造訪 → 只在同一次導覽內做加法,彙整層直接計算最終指標百分位。
- 部署當天看到 RUM 下降就宣告完成 → 樣本、流量組成和 28 天視窗尚未穩定 → 灰度比較、檢查守護指標,並等待滾動 field data 確認。
追問及應對
追問一:為什麼 field LCP 很差,但在多台測試手機上都無法重現?
先檢查 field 值是 URL 還是 origin、頁面樣板是否正確分組,以及慢樣本集中在哪個地區、網路、導覽類型或版本。測試裝置沒有涵蓋真實尾端時,應從 RUM 的慢導覽取出低基數環境標籤,重建接近的 CPU、網路、快取與登入狀態。仍無法重現時保留線上歸因資料,不能透過重複執行快速裝置把問題「測掉」。
追問二:只有某個低階 Android 群體的 INP 失敗,整體 p75 已達標,還要修嗎?
先核對該群體的造訪量、業務重要性與樣本可靠性。全域門檻達標只表示整體分布,不代表每個重要群體都可接受。若該裝置層涵蓋大量付費使用者或 INP 遠超 500 毫秒,應建立細分 SLO 並處理;樣本很少時先提高可觀測性。不能把所有細分都設成硬門檻,否則小樣本雜訊會阻擋發布。
追問三:LCP 元素是使用 Web Font 的標題文字,不是圖片,方案怎樣改變?
資源發現重點從圖片改成字型與阻塞樣式。檢查字型請求何時被發現、是否跨網域連線、字型檔案大小、font-display 和備援字型尺寸;同時確認標題是否等待客戶端渲染。不能照搬 fetchpriority 圖片方案。預先載入字型也只針對首屏確實使用的檔案,並驗證沒有重複下載或搶占更關鍵資源。
追問四:慢互動發生在跨網域付款 iframe 內,頂層頁面只看到 INP 變差怎麼辦?
INP 可以反映頁面中 iframe 互動的使用者延遲,但跨網域邊界會限制頂層頁面歸因。先依嵌入版本與出現頁面關聯 RUM,使用供應方提供的效能資料或可重現測試與其協作;頂層頁面也可減少同時執行的自身長工作。無法觀察內部呼叫堆疊時應明確說明證據邊界,不能直接把問題歸因給供應方,也不能聲稱已在本機程式碼中修復。
追問五:頁面流量太少,CrUX 沒有 URL 級資料,怎樣判斷是否達標?
使用第一方 RUM 採集每次造訪的指標與必要環境欄位,並報告樣本量和時間窗;同時用實驗室關鍵路徑測試防回歸。可以用樣板級彙整提高樣本,但必須確保頁面結構與使用者路徑可比較。沒有足夠資料時可以證明已修復已知 trace,卻不能聲稱取得 CrUX URL 級「良好」狀態。
追問六:提前渲染 Hero 讓 LCP 下降,卻讓 hydration 更早執行,INP 上升怎麼辦?
這是指標間的真實權衡,不能只保留 LCP 改善。檢查提前渲染是否必須伴隨更早 hydration;通常可以先輸出靜態可見內容,把互動程式碼依需要載入。若業務確實要求立即可互動,就依關鍵使用者動作決定預算,拆分主執行緒工作並灰度比較 LCP、INP 和轉換,不能用一個綜合效能分數掩蓋 INP 退化。
追問七:隱私規則禁止保存完整 URL 與 DOM 目標,RUM 還能定位嗎?
可以使用預先定義的路由樣板、元件列舉、互動類型、發布版本和粗粒度裝置等級,不保存商品 ID、查詢參數、文字或使用者識別碼。客戶端在上報前完成映射,伺服器端拒絕高基數欄位。歸因精度會下降,因此實驗室重現要圍繞列舉出的元件與路徑補足;效能診斷不構成擴大個人資料採集的理由。