本文說明如何使用 DevTools 找出瀏覽器繪製階段的瓶頸,並結合 GPU 與合成層(Compositing Layer)的機制優化動畫效能。
建構視角的對應章節:瀏覽器渲染流程
概覽#
當動畫出現效能問題時,光看 Performance 面板上一長條的綠色繪製區塊很難定位真正原因。通常會搭配 DevTools 的其他面板觀察繪製過程與 layer 資訊,主要工具有三個:
- Paint Profiler:呈現繪製(Paint)階段中所有步驟的細節與時間軸。
- Layers tool:列出所有 layer 並把它們在頁面中視覺化呈現。
- Rendering tab:直接在頁面標出 layer 邊界與重繪區塊。
工具介紹#
Paint Profiler#
使用前要先在 Performance 面板的設定中開啟 Enable advanced paint instrumentation,這樣繪製過程中每一步才會被紀錄。錄製後點擊 Paint 區塊,下方會多出 Paint Profiler 分頁,內容由三部分組成:
- 整段繪製流程的時間軸
- 每一道繪製指令
- 每個時間點的繪製結果
時間軸上柱體長度代表花費時間,可以拖選一小段檢視該段內的指令與當下結果。指令列中常見如 drawTextBlob 用於繪製文字,展開後可以看到座標、顏色等屬性,也會出現 save、restore、translate 這類常見於 Canvas 的指令。
Layers Tool#
從 More tools 進入 Layers 面板,左側列出頁面所有 layer,點擊任一個(或在中央視覺化區直接選取)就能看到大小、產生原因、記憶體用量等細節。上方工具列可以切換顯示模式,畫面太亂時可以關掉 Paints 選項只留 layer 邊界。
Frames#
開啟 Enable advanced paint instrumentation 後,點擊 Frames 中任一幀也會看到 Layers 分頁,介面與 Layers 面板一致,適合觀察特定一幀的 layer,且能避開動畫太多時 Layers 面板卡住的狀況。
Rendering Tab#
按下 ESC 展開 Drawer,於選單中找到 Rendering tab。與繪製最相關的兩個選項:
- Paint flashing
- Layer borders
Paint flashing#
把頁面中正在重繪的區域以綠色框標出,框越多越大代表繪製成本越高。如果某個內容幾乎沒變化卻不斷被重繪,就值得考慮把它獨立成自己的 layer。
Layer borders#
不只看哪裡被重繪,還能標示 layer 邊界。被獨立出來的 layer 會以橘色框線標示,藍綠色框線則代表 tile —— 一個 layer 會被切成多個 tile 以加速繪製,切割方式由瀏覽器決定。
實際範例#
開啟示範頁面後會看到滿滿的方塊,按下 Animate 讓方塊轉圈時頁面明顯卡頓;切換到 Isolate 後動畫立刻變得流暢。
把剛剛介紹的工具拿來檢查就能找到原因。
Performance#
未獨立 layer 時 FPS 平均只有 20,下方有一大串綠色繪製區塊,GPU 幾乎沒在休息;獨立 layer 後 FPS 幾乎穩定在 60。
Layers Tool#
未獨立時只看到一片大的 layer,獨立後每個方塊都長出自己的 layer。
Paint flashing 與 Layer borders#
未獨立的版本會看到整個畫面瘋狂重繪,獨立後幾乎沒有重繪事件;layer borders 也清楚顯示橘色框已經圈住每個方塊。
解釋#
原本範例用 transform: translate(); 讓方塊轉圈,按 Isolate 後改成 transform: translate3d();(與 transform: translateZ(); 同效),會把元素獨立成新的 layer。原本要一直重繪整個畫面,變成只是移動 layer 再合成,幾乎不需要重新繪製。
加上 will-change: transform; 也能達到同樣的效果,把元素提升到新的合成層。
原文出處#
- 原書/iThome:https://ithelp.ithome.com.tw/articles/10249933