iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 23
1
Modern Web

你所不知道的各種前端 Debug 技巧系列 第 23

[Day 23] Performance - Analyze Paint & Layers

本文將會講解如何利用 DevTools 找出瀏覽器繪製頁面的效能瓶頸,並利用 GPU 和瀏覽器繪製頁面的機制來優化動畫效能,閱讀本文前建議先理解瀏覽器繪製頁面的流程,可以參考 Performance - How Rendering Works

概覽

網頁中的動畫出現效能問題時,光看 Performance 面板中的長長的綠色區塊很難找出造成瓶頸的原因,一般會搭配 DevTools 中的其他面板來觀察繪製過程和 Layer 資訊,它們分成三個部分:

  • Paint Profiler – 顯示 Paint 階段中所有步驟的細節、時間線
  • Layers tool – 顯示所有 Layer 的細節,並將頁面中的 Layer 視覺化
  • Rendering tab – 直接在畫面中標註 Layer 的邊界和重繪的區塊

有了這些工具,就能開始分析頁面造成效能瓶頸的原因並針對該部分進行優化。

 

工具介紹

Paint Profiler

使用 Paint Profiler 之前,需要開啟 Performance 設定的 Enable advanced paint instrumentation 選項,才能在 Paint 的過程中紀錄每個步驟:

開啟 Paint Profiler 後,隨意進入一個網頁,重新整理錄製效能資訊,點擊 Paint 區塊會發現詳細資訊面板多了一個 Paint Profiler 分頁,裡面由三個部分組成:

  • 整個繪製流程的時間線
  • 每一道繪製指令
  • 每個時間點的繪製結果

時間線中柱體的長度代表花費的時間,可以在時間線中拖曳一小區段,來看看特定時間內的繪製指令和對應的結果。

指令列表中很明顯可以看出 drawTextBlob用來繪製文字,展開能看到座標、顏色等等屬性,還有 Canvas 中很常見的 saverestoretranslate 指令。

 

Layers Tool

在 More tools 中可以看到 Layers 面板,點擊後會顯示目前的 Layer 資訊,左側可以看到頁面中總共有哪些 Layers,點擊 Layers 列表或是中間視覺化區域內的 Layer 可以看到詳細資訊,包括 Layer 的大小、產生的原因、記憶體用量。

另外可以用上方的工具列來把玩視覺化的 Layers,畫面過於混亂時可以關掉 Paints 選項只顯示所有 Layers 的邊界。

Frames

如果有打開 Enable advanced paint instrumentation 選項,點擊 Frames 中任意一個 Frame 會看到 Layers 分頁,介面和剛剛說明的 Layers 面板相同,用來觀察特定一幀的 Layers 資訊,也可以避免畫面大量動畫讓 Layers 面板跑不動的問題。

 

Rendering Tab

透過 Rendering Tab 能夠最快速的看出 Paint 的問題,按下 ESC 展開 Drawer,選單中可以找到 Rendering Tab,其中和 Paint 最相關的選項有:

  • Paint flashing
  • Layer borders

為什麼拖曳視窗的時候視窗沒有重繪?

Paint flashing

顯示頁面重繪的區域,通常綠色的框框越多、越大,就需要花越多時間繪製,如果發現一塊幾乎沒有變化的區域不斷被重繪,可以考慮把該區塊獨立為一個 Layer。

Layer borders

Paint flashing 只能看出重繪的區域,Layer borders 則會顯示 Layer 的邊界,被獨立出來的 Layer 會以橘色框線標示。

藍綠色的框線代表 Tile,一個 Layer 會再被切分為多個 Tiles 來加速繪製,不過怎麼切分就只能交給瀏覽器自己決定了。

關於 Tile 和 Raster 在 Performance - How Rendering Works 中皆有介紹。

 

實際範例

打開範例網站後,會看到一大堆方塊,按下 Animate 方塊會開始轉圈,會發現頁面卡卡的,此時按下 Isolate 會發現動畫變順了。(若原本就很順就多開幾個分頁)

不知道為什麼?把剛才提到的工具拿來試試吧!

Performance

左半邊的 FPS 平均只有 20 ,下方有一大串代表繪製的綠色方塊,GPU 幾乎沒有休息;右半邊獨立 Layer 後 FPS 幾乎維持在 60

Layers Tool

原本只有一片平坦的 Layer,獨立 Layer 後長出一條 Layer 龍

Paint flashing

獨立 Layer 優化 VS 瘋狂重繪

Layer borders

原本 VS 獨立 Layer

解釋

原本 Demo 頁面中的方塊是透過 transform: translate(); 來轉圈,點擊 Isolate 後會改為 transform: translate3d();,效果和 transform: translateZ(); 相同,會把該元素獨立到新的 Layer,原本不斷重繪整個畫面,變成稍稍移動 Layers 再進行合成,完全不用繪製。

此外在 CSS 的 .box 加入一條 will-change: transform; 也會把方塊獨立到新的 Layer。

 

Credits

http://udacity.github.io/60fps/lesson6/willChange/index.html
https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/reference


上一篇
[Day 22] Performance - Rendering Optimization
下一篇
[Day 24] Performance - Analyze Memory
系列文
你所不知道的各種前端 Debug 技巧30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
Dylan
iT邦新手 3 級 ‧ 2020-10-25 22:43:42

發現個錯字
Canvas 中很常見的 save、resotre、translate
resotre -> restore

shizuku iT邦新手 5 級 ‧ 2020-10-28 22:16:56 檢舉

已修正 :D

我要留言

立即登入留言