效能優化的常見討論往往集中在「載入時間」上,例如程式碼分割、Lazy Loading 等手段。但是頁面載入完之後,使用者真正在操作網頁時的流暢度(Runtime Performance),才是體驗的關鍵。本章聚焦在 Chrome DevTools Performance Panel 的使用方式,看看怎麼用它揪出 runtime 階段的效能瓶頸。
開始 Profiling#
實務建議 進行 profiling 前,建議使用無痕視窗以避免擴充功能干擾測量結果。
DevTools 的 Performance Tab 左上角有兩顆按鈕:
- Record:點擊後手動操作網頁,再停止錄製。適合測試特定行為。
- Start profiling and reload page:自動 reload 並錄製,適合測試初始載入。
如果想模擬低階手機,可以在工具列的 CPU 選項調整速率(例如 6x slower),確保即使在效能較差的裝置上也能保持流暢。
解讀 FPS、CPU、NET 圖表#
FPS(Frame Per Second)#
動畫流暢度的最直觀指標,目標通常是 60 FPS。圖表中若出現紅色或粉紅色的條塊,代表掉幀,動畫可能不平順。FPS 過低不一定全是壞事,例如頁面靜止時本來就不需要持續產出新 frame。
CPU 與工作種類#
CPU 圖表會以不同顏色代表工作類別,與 Summary 對應:
| 顏色 | 類別 | 說明 |
|---|---|---|
| 灰色 | System | 瀏覽器內部任務 |
| 白色 | Idle | 閒置時間 |
| 黃色 | Scripting | JavaScript 執行與事件處理 |
| 綠色 | Painting | 繪圖、畫面繪製 |
| 紫色 | Rendering | 樣式計算、版面配置(Layout) |
| 藍色 | Loading | 載入與解析 HTML |
CPU 長期 maxed out 不一定是壞事(例如有持續動畫的網站),但若伴隨大量 Scripting 與掉幀,就值得審視是否能精簡程式碼,或把動畫改用 CSS 達成。
Memory:找出記憶體洩漏#
點開 Memory 選項可以看到藍色的 JS Heap 趨勢線。若曲線只升不降,很可能存在記憶體洩漏(Memory Leak)。也可以利用 GC 強制按鈕(垃圾桶圖示):
- 在執行某段函式前後分別強制 GC。
- 如果記憶體仍居高不下,洩漏的可能性就很大。
不過 GC 太頻繁也未必是好事——標記-清除(Mark-and-Sweep)會造成 Stop-the-world,太頻繁會直接影響流暢度。
Frames:每一幀的細節#
Frames 區塊呈現每一次 UI 更新的截圖。長時間沒更新的 frame 稱作 long frame。點擊單一 frame 可以在 Summary 看到 Duration、FPS、CPU Time 等資訊,便於精確定位卡頓的時刻。
Timing:載入相關指標#
Timing 顯示頁面在載入過程中觸發的關鍵時間點:
| 縮寫 | 全名 | 說明 |
|---|---|---|
| DCL | DOM Content Loaded | HTML 被解析完成的時間 |
| FP | First Paint | 第一個像素被繪製的時間 |
| FCP | First Contentful Paint | 第一個有意義內容(文字或圖片)出現的時間 |
| LCP | Largest Contentful Paint | 可視區內最大元件載入完成的時間 |
| L | onload | 所有資源載入完成的時間 |
| TBT | Total Blocking Time | Main Thread 被阻塞的累計時間,越短越好 |
Experience:找出 Layout Shift#
Experience 區塊會標出觸發 Layout Shift 的時刻,正是 Core Web Vitals 中的 CLS 指標來源。
Network:資源依賴關係#
Network 顯示各資源的下載時序與依賴。雖然 Network Tab 通常更直覺,但在 Performance Tab 中可以與 CPU 任務疊在一起看,方便對照。
Main:CPU 火焰圖(Flame Graph)#
Main Section 是 Main Thread 的火焰圖(Flame Graph),呈現每一個 task 與其呼叫的子任務。圖中越下層的 task,越是在某個 parent task 內被觸發的。
Long Task 警告#
若 task 的右上角出現紅色三角形,代表這是一個 long task,可能是效能瓶頸。點選後可以看到呼叫堆疊與來源檔,甚至直接跳到 Sources Tab 對應的程式碼行數,對除錯非常方便。
除了 Main,可能還會出現 Frame(嵌入 iframe 的執行緒)與 Worker(例如 Web Workers)等項目,方便分析多執行緒場景。
範例:動畫前後的對比#
回到範例網站,原本的動畫直接改變元素的 top:
element.style.top = `${currentTop + 1}px`;這會觸發重新計算版面配置(Layout),Main Thread 一直忙在 Painting 與 Rendering 上,Idle 時間極少,掉幀嚴重。改用 transform 後:
element.style.transform = `translateY(${y}px)`;<style>
.item {
will-change: transform;
}
</style>此時動畫只需在合成層上更新,不必觸發 Reflow / Repaint,profiling 出來的結果:
- Frame Rate 大幅提升。
- CPU 使用量降低。
- Idle Time 變多,能即時回應使用者輸入,TTI(Time to Interactive (TTI))也跟著改善。
補充說明 Lighthouse 分數高並不等於使用體驗好。曾有 Lighthouse 滿分卻在實際操作時卡頓的案例,這時 Performance Tab 的 runtime profiling 才是抓問題的關鍵工具。
小結#
Chrome DevTools Performance Panel 提供的資訊量豐富,初次看到容易眼花。掌握 FPS、CPU、Memory、Frames、Timing、Experience、Main 等核心區塊,已經足以應付大多數 runtime 除錯需求。下次遇到卡頓或失幀時,不妨從這裡著手,配合火焰圖(Flame Graph)找出真正的瓶頸所在。