Chrome DevTools Performance 面板怎麼看:從 trace 找出 LCP、INP 與 JavaScript 瓶頸
用 Chrome DevTools Performance 面板錄製 trace,判讀 main thread、long task、LCP、INP 與 layout shift,區分網路、主執行緒、渲染延遲與互動卡頓,找出真正該修的效能瓶頸與驗證順序。
陳柏翰
網站效能工程師
Performance 面板是 Chrome DevTools 裡最被低估的工具。多數工程師打開它、截個圖,然後把紅色的 long task 截下來說「找到問題了」,但紅色任務可能有十幾條,哪一條才是真正拖慢 LCP 的那個,很少有人說得清楚。這篇文章記錄我用 Performance 面板調過十幾個站之後整理出來的讀法,從錄製條件、區塊判讀到 Core Web Vitals 的診斷流程,以及最後怎麼把 trace 轉成真正可執行的修復清單。
Chrome DevTools Performance 面板到底在看什麼
Chrome DevTools Performance 面板是用來錄製頁面載入或互動過程的 trace,讓你看到瀏覽器在每個時間點做了 loading、scripting、rendering、painting 還是 interaction work。它不是 PageSpeed Insights,不是 Lighthouse,也不是 CrUX。詳細的官方說明可以參考 Chrome DevTools Performance 面板總覽。
這個差異非常重要。PSI 的分數混合了 Lighthouse lab run 和真實使用者的 CrUX field data,你看到的 LCP 數字是 28 天滾動平均或單次 lab 測試。Performance 面板的 trace 是你本機這台電腦、這個網路、這個時間點的單次錄製。兩個數字不一樣完全正常,用 Performance 面板找到的問題,不見得立刻反映在 PSI 分數裡。
Performance 面板的優勢在於時間解析度。你能看到 main thread 在 1,204ms 那個時間點在執行哪一段 JavaScript,知道是哪個 event listener 觸發了 layout,哪個 third-party script 在 LCP 前佔用了 350ms。這是 Lighthouse 報告給不了你的細節。
要詳細了解 PSI 和 Lighthouse 數字差異的原因,可以看 PageSpeed Insights 分數為什麼每次都不一樣 這篇。
錄 trace 前先把測試條件鎖住
錄 Performance trace 前,至少要固定七個條件,否則兩次 trace 差距可能只是測試環境不同,根本沒辦法比較。
| 條件 | 設定方式 | 為什麼重要 |
|---|---|---|
| 關閉擴充功能 | 無痕視窗或停用所有 extension | 擴充功能會在 main thread 注入 script,影響 trace 數據 |
| 清空快取 | DevTools > Network > Disable cache,或錄製時勾選 Empty cache and hard reload | 有快取的載入速度遠快於首次訪客看到的狀態 |
| CPU 節流 | Performance 面板右上齒輪 > CPU: 4x slowdown | 開發機 CPU 通常比手機快 4-6 倍,不降速等於自欺欺人 |
| 網路節流 | 齒輪 > Network: Fast 3G 或 Slow 3G | 模擬真實使用者的網路環境,才能重現 render-blocking 問題 |
| 固定錄製觸發點 | 頁面載入用 Start profiling and reload page;互動問題用手動 Record | 兩種模式錄製的起點不同,不能混著比較 |
| 使用隱私視窗 | Ctrl+Shift+N 開啟,再打開 DevTools | 排除登入狀態、A/B test cookie、個人化內容的干擾 |
| 同一個測試路徑 | 每次錄製同一個 URL,不要今天測首頁、明天測分類頁 | 不同頁面的 resource graph 完全不同,無法比較 |
設定好之後,我習慣的格式是:先錄一次當 baseline,改一個變因,再錄三次,比較 median。不要只跑一次就下結論,DevTools 的 simulated throttling 有 ±15% 的波動是正常的。
一次 Performance trace 會錄到哪些資料
一次 trace 會記錄時間軸總覽、CPU 活動、網路請求、畫面截圖、使用者體驗事件與 main thread 工作;底部面板則用 Summary、Bottom-up、Call tree 和 Event log 讓你下鑽。
面板從上到下分成三個區域:
上方 Overview(縮覽圖):有三個子軌,FPS 顯示影格率曲線(綠色是順暢,紅色是掉幀);CPU 是疊加的顏色條(黃色 Scripting、紫色 Rendering、綠色 Painting、灰色 Loading、橙色 Idle);NET 是請求瀑布概覽。Overview 的作用是讓你拖拉縮放看哪個時間段值得深挖,不是在這裡判斷問題。
中間時間軸軌道:從上到下依序是 Network(每個 HTTP 請求的 timing bar)、Screenshots(頁面畫面快照)、Experience(LCP 事件、layout shift 記號)、主 thread 的 Main 軌道,以及其他 Workers 和 GPU 的輔助軌道。Main 軌道是你花最多時間看的地方。
底部分析面板:選取一段時間範圍後,Summary 顯示各類型工作的比例餅圖;Bottom-up、Call tree、Event log 讓你深入追蹤具體的 function 或 event。
先看 Main thread,不要一開始就追每個 function
看 Performance trace 時,先在 Main thread 找最長、最密、最靠近關鍵指標的工作區塊,再下鑽 function call;一開始就追每個 function 只會浪費時間。
先判斷瓶頸類型,再決定要不要追 function call。
三步讀法:
- 找最長任務:在 Main thread 區塊裡,最長的灰色條就是耗時最多的任務。Chrome 會在超過 50ms 的任務頂部標一個紅色三角形,這就是 long task 的視覺標記。先圈出這三到五條最長的任務。
- 看工作類型:把滑鼠停在任務上,Summary 面板會顯示這個任務主要是 Scripting、Rendering、Painting 還是 Loading。四種類型代表不同的瓶頸方向:Script 太胖要看 JS;Rendering 太多要看 style recalculation 和 layout;Painting 太密要看 layer 和 composite;Loading 卡著要看 network 和 render-blocking resource。
- 下鑽原因:鎖定目標任務後,點擊 Bottom-up 或 Call tree,找到實際耗時的 function call 或 browser event,才是真正的修復起點。
Long task 的技術定義是阻塞 main thread 超過 50ms 的工作。50ms 這個閾值來自「使用者感知卡頓約在 100ms 以上」的研究,瀏覽器需要留緩衝來確保即時回應。單一 long task 不一定會影響 Core Web Vitals,但連續的 long task 或發生在關鍵渲染路徑上的 long task,會直接推高 LCP 或 INP。
Main thread 的問題常和 JavaScript 效能瓶頸 直接相關。如果看到大量 Script evaluation 或 Compile Script,可以對照那篇的 bundle analyzer 診斷流程。
用 Performance trace 找 LCP 問題
LCP 慢不一定是圖片太大;在 Performance trace 裡要同時看 LCP marker 前的網路請求、main thread blocking、render delay 和圖片 decode,才能判斷真正的瓶頸在哪。
LCP 慢要先分清楚是網路、主執行緒還是渲染延遲。
在 Experience 軌道找到 LCP marker 後,對應時間點往上看 Network 軌道,往下看 Main thread,可以把 LCP 問題拆成四條路徑診斷:
| 路徑 | trace 線索 | 常見修法 |
|---|---|---|
| 資源載入慢 | LCP 元素(圖片或文字)在 Network 軌道的請求開始很晚,或下載時間很長 | preload、CDN、HTTP/2、圖片格式換 AVIF/WebP |
| Render-blocking 拖延 | HTML parse 完後 main thread 一直在跑 Script evaluation 或 Parse Stylesheet,LCP 資源的請求被推遲 | async/defer JS、critical CSS inline、移除非關鍵 third-party script |
| Main thread blocking | LCP 資源下載完成(Network 軌道已結束),但 main thread 還在跑別的 long task,LCP rendering 一直等到 task 結束才能執行 | 分割 long task、推遲非必要 JS、setTimeout/yield |
| Image decode 延遲 | LCP 元素下載完成後,main thread 出現 Decode Image 的 task,decode 時間超過 50ms | 使用更高效格式(AVIF decode 通常比 PNG 快)、伺服器端縮圖避免在客戶端 decode 超大圖 |
實際案例:我測過一個電商首頁,PSI 回報 LCP 3.8s,Lighthouse 說問題是圖片沒有 lazy loading。但用 Performance trace 看,hero image 下載時間只有 380ms,LCP 之所以到 3.8s,是因為 main thread 在 0-2,800ms 這段時間都在跑一個 third-party analytics script 的初始化,等 script 執行完,LCP 才能渲染。修法不是改圖片格式,是把 analytics 延遲到 DOMContentLoaded 之後載入,LCP 從 3.8s 降到 1.6s。
LCP 指標的完整定義與計算方式可以參考 web.dev LCP 文件。深入了解 LCP 優化方法可以看 LCP 優化實戰:四段時間模型。
用 trace 看互動卡在哪:INP 和 long task
INP 問題通常要從 interaction event 附近找 long task,並拆成 input delay、processing duration、presentation delay 三段來判斷是哪裡卡住。
錄製 INP 問題的方式和載入 trace 不同。要手動按 Record,然後在頁面上點擊或操作你想測的互動(例如開啟選單、送出表單),再停止錄製。在 Experience 軌道找到 INP marker,展開來看三段組成:
| 階段 | 代表什麼 | 在 trace 哪裡看 | 常見原因 |
|---|---|---|---|
| Input delay | 從使用者輸入到瀏覽器開始處理的等待時間 | Interaction event 前的 main thread 被其他 task 佔用 | 後台執行的 timer、analytics 輪詢、其他 event handler |
| Processing duration | event handler 實際執行的時間 | Interaction event 本身的 task 長度 | handler 裡有同步的 DOM 操作、state 更新、forceLayout |
| Presentation delay | handler 執行完到畫面更新之間的等待 | Interaction event 後到下一次 commit frame 的時間 | style recalculation、paint、composite 佔用太多時間 |
實際案例:一個按鈕點了 280ms 後才更新 UI,trace 顯示 input delay 只有 12ms,processing duration 也只有 40ms,但 presentation delay 高達 228ms。鎖定 presentation delay 後發現,點擊後觸發了一個重新計算 480 個元素 grid layout 的 CSS 更新,改成只更新點擊按鈕本身的 class,presentation delay 降到 18ms,整體 INP 從 280ms 降到 70ms。
INP 三段組成的官方定義可以參考 web.dev INP 文件。INP 問題的深度診斷可以看 INP 優化:診斷主執行緒瓶頸。
Layout shift 不是只看紅線:CLS 怎麼回推原因
在 Performance 面板看到 layout shift 後,要回到 shift cluster、受影響元素和發生前後的 DOM / resource 變化,才能判斷是圖片尺寸、字體交換還是 late insertion。
Layout shift 要回到元素和發生前後的資源變化看。
Experience 軌道裡的藍色竪線就是 layout shift record。點擊後,Summary 面板會顯示:
- Cumulative Score:這次 shift 的分數貢獻
- Had recent input:是否在使用者輸入後 500ms 內發生(有的話不算進 CLS)
- Impacted nodes:哪些 DOM 元素被位移了
有了受影響元素,就能回去 Main thread 找對應時間點前後發生了什麼:
| CLS 原因 | trace 特徵 | 修法 |
|---|---|---|
| 圖片無尺寸 | shift 時間點吻合 Network 裡某張圖片下載完成的時間點 | HTML 加 width/height 或 aspect-ratio CSS |
| Font swap 觸發 | shift 吻合字體下載完成後的 Re-render,Main thread 有大範圍 Style recalculation | font-display: optional 或 preload 字體,減少 FOUT 幅度 |
| 動態插入 banner 或廣告 | shift 發生在 DOMContentLoaded 之後,Main thread 有 DOM insert 類的 JavaScript call | 預留廣告位置、固定 min-height |
| 動畫使用非 transform 屬性 | 連續多個 shift record,Main thread 每個 frame 都有 Layout task | 改用 transform/opacity,避免觸發 layout |
CLS 的計算方式與閾值定義可以參考 web.dev CLS 文件。CLS 的完整修法可以看 CLS 意思是什麼:版面位移的計算公式與診斷方式。
Bottom-up、Call tree、Event log 怎麼選
Bottom-up 適合找總耗時最高的 function,Call tree 適合追某段流程怎麼被呼叫,Event log 適合按時間順序檢查特定事件。
這三個 tab 都在 DevTools 底部面板,選取一段 Main thread 時間範圍之後才會顯示該範圍的資料。
| Tab | 排序邏輯 | 適合用來 | 典型任務 |
|---|---|---|---|
| Bottom-up | 從葉子節點往上聚合,依 Self Time 或 Total Time 排序 | 找耗時最多的 function,不論它被哪裡呼叫 | 「選取範圍裡哪個 function 最肥」 |
| Call tree | 從根節點往下展開,依呼叫鏈顯示 | 追某段流程是從哪個入口觸發,到底怎麼一路呼叫下去 | 「這個 React re-render 是被哪個 event 觸發的」 |
| Event log | 按時間順序列出所有 event | 找某個時間點發生了什麼,或確認 event 觸發的先後順序 | 「DOMContentLoaded 和 LCP 中間有哪些 event」 |
實務上我最常用 Bottom-up。選取一個 long task 的時間範圍,底部切到 Bottom-up,按 Total Time 降冪排列,通常第一條就是要追查的目標。找到函式名稱後,點右側的 source link 可以直接跳到 Sources 面板看原始碼。
DevTools、Lighthouse、PageSpeed Insights、WebPageTest 差在哪
DevTools Performance 適合找 local runtime bottleneck;Lighthouse 適合做 lab audit;PageSpeed Insights 混合 lab 和 CrUX field data;WebPageTest 適合做可重複的網路與視覺載入分析。
在這篇的工具比較表格之外,如果你還在用舊版 Web Vitals Chrome Extension,需要知道Web Vitals Chrome Extension 已移入 DevTools:正確的 2026 工具選擇。
| 工具 | 資料來源 | 適合做什麼 | 不適合做什麼 |
|---|---|---|---|
| DevTools Performance | 本機 local trace | 找 runtime 瓶頸、追 function call、確認 long task 原因 | 代表真實使用者體驗、跨裝置重現 |
| Lighthouse | Lab data(模擬環境) | 稽核 best practice、找 audit 問題清單、CI/CD gate check | 代表 field data、定位 runtime 問題細節 |
| PageSpeed Insights | Lab + CrUX field data | 查看真實使用者的 Core Web Vitals 評等、比對 lab vs field 落差 | 定位具體 function 瓶頸、debug runtime 問題 |
| WebPageTest | 真實裝置或 VM,可重複執行 | 跨地點、跨裝置、跨網路的標準化對比測試,filmstrip 視覺分析 | 本地開發環境的 runtime debug |
工具分工的核心原則:DevTools 是顯微鏡,WebPageTest 是控制組對比實驗,PSI 是告訴你真實使用者的狀況。不要拿顯微鏡讀出來的數字去和真實使用者的 CrUX 比較,它們問的是不同問題。
有一點要說清楚:Performance trace 是診斷證據,不是排名保證。trace 改善代表你找到了問題並在本機驗證了修法,但不等於 CrUX field data 一定跟著動,也不等於 Google 搜尋排名一定改變。field data 需要真實使用者在真實裝置和網路條件下造訪後才會更新,simulated throttling 的結果和真機 field data 之間永遠存在落差。
從 trace 轉成修復清單:不要看到紅色就先改
修復順序應該看指標影響、問題重現率和實作成本,不是看到 trace 裡哪一段最紅就先改哪一段。trace 裡最長的 long task 不一定影響使用者看到的 Core Web Vitals,修最長的不等於修最重要的,要用系統化的方式排出優先順序才能把有限工時花在真正有效的地方。
Trace 只是證據,修復順序還要看影響、重現率和成本。
我用的 priority score 公式:
Priority = (指標影響分 × 重現率分) ÷ 實作成本分
每個維度用 1-3 分評估:
| 維度 | 1 分 | 2 分 | 3 分 |
|---|---|---|---|
| 指標影響 | 只影響 lab data,field data 不動 | 影響 1 個 Core Web Vitals 指標 | 影響 2 個以上或直接影響 CrUX 評等 |
| 重現率 | 偶發,難穩定重現 | 大多數 trace 都能看到 | 每次錄製都重現,有明確觸發條件 |
| 實作成本 | 需要重構或跨團隊協調(高成本=1分) | 需改 1-2 個檔案,不影響功能 | 一行 HTML/CSS 可解決(低成本=3分) |
Priority score 最高的先做。舉例:一個圖片加上 width/height 屬性(成本 3 分)、每次 trace 都有 shift(重現率 3 分)、CLS 目前是 Poor(指標影響 3 分),priority = (3×3)÷3 = 3。相比之下,一個需要重構 bundle(成本 1 分)才能改善 0.2s LCP(指標影響 2 分)、只在 slow 3G 能重現(重現率 1 分)的問題,priority = (2×1)÷1 = 2。先做前者。
改完後怎麼驗證:一個單一變因實驗流程
改完效能問題後,先保留 baseline,再只改一個變因,重跑三次 trace 和 lab test,比較 median,最後再用 field data 驗證是否真的改善。
實驗流程:
- 記錄 baseline:在改之前,用固定的測試條件錄製三次 trace,記下 LCP、long task 最長值、INP(如果有互動測試),取 median 作為 baseline。同時跑一次 PSI,記下 lab 分數和 field data 評等。
- 只改一個變因:一次只改一件事。例如只加 preload 那一行,不要同時改圖片格式和延遲載入 analytics。
- 重新錄製三次:用和 baseline 完全相同的條件,再錄三次。
- 比較 median:把兩組各自的 median 拿來比。如果 median 改善超過 15%,才算顯著改善(15% 是 DevTools simulated throttling 的正常波動範圍)。
- Field data 驗證:Lab trace 改善之後,等 28 天讓 CrUX 資料更新,再用 PSI 或 CrUX API 確認 field data 是否跟著動。Lab 改善但 field 沒動,代表這個改動沒有影響到大多數真實使用者的路徑。
| 驗證點 | Baseline 記錄 | After 改善目標 |
|---|---|---|
| LCP(DevTools trace median) | 記錄改動前的 median 值 | 降低 ≥ 15% |
| 最長 long task(ms) | 記錄改動前最長 task 的毫秒數 | 降低 ≥ 50ms |
| INP(互動 trace median) | 記錄改動前的互動 median | 降低至 < 200ms |
| CLS(Experience track sum) | 記錄改動前的 shift score 總和 | 降低至 < 0.1 |
| PSI lab score | 記錄改動前的 Lighthouse 分數 | +5 分以上 |
| CrUX field data(28 天後) | 記錄改動前的 field 評等 | 評等提升 |
Performance 面板是診斷工具,不是答案。Trace 告訴你哪裡慢、慢多少、什麼類型的工作在消耗時間;怎麼修、改什麼、改完有沒有效,需要透過單一變因實驗和 field data 驗證來確認。光是「在 trace 裡找到 long task」不算找到問題,能把 long task 的 median 時間壓下來並看到 CrUX 跟著改善,才算完成一輪診斷。
關於 Core Web Vitals 各指標的成因與修法,Core Web Vitals 完全指南 有各指標的完整工程說明。
常見問題
以下整理 Chrome DevTools Performance 面板最常見的操作疑問,幫助你快速釐清工具邊界、long task 閾值和 trace 資料的代表性。
Chrome DevTools Performance 面板和 Lighthouse 有什麼差別?
Performance 面板錄製的是本機 runtime trace,你能看到每個 function 和 browser event 的執行時間。Lighthouse 跑的是模擬環境的 lab audit,回傳的是結構化的 best practice 清單和各項評分。兩個工具要一起用:先用 Lighthouse 找問題方向,再用 Performance 面板定位具體瓶頸。
Long task 超過 50ms 就一定要修嗎?
不一定。長度超過 50ms 只是 long task 的定義門檻,代表有阻塞 main thread 的風險。要不要優先修,取決於它是否發生在 LCP 渲染前、INP 互動期間、或 CLS 觸發前後。發生在使用者不關心的時間段的 long task,修了對 Core Web Vitals 不會有明顯改善。
Performance trace 可以代表真實使用者的體驗嗎?
不能直接代表。Performance trace 是單次本機錄製,受限於你的機器、網路和 Chrome 版本。真實使用者的體驗資料在 CrUX field data 裡,可以透過 PageSpeed Insights 或 CrUX API 查詢。trace 的作用是找到問題根源,field data 的作用是確認問題是否普遍存在且改善後是否真的有效。
Chrome DevTools Performance 面板哪裡找?
開啟 Chrome,按 F12 或 Ctrl+Shift+I 打開 DevTools,點擊頂部 tab 列的「Performance」。如果找不到,點擊 tab 列最右側的「»」展開隱藏的 tab,或用 Ctrl+Shift+P 開啟命令選單搜尋「Performance」。