如何優化像素管道的 Paint 和 Composite?
20 Jul 2018更詳細探討如何優化像素管道(Browser Rendering Pipeline)的繪製(Paint)和合成(Composite)這兩個階段。
繪製(Paint)
Paint Flashing
若想知道繪製(Paint)發生於何時何處,可使用 Chrome DevTools > More tools > Rendering > 勾選 Paint flashing,開啟後檢視畫面,發生繪製時該區塊會閃綠光。
範例如下圖,scroll 這個網站,閃綠光的地方就是當下發生繪製之處。
每次繪製的區塊原來有這麼大!該縮小繪製區域了。
Paint Profiler
若想知道繪製細節,可使用 Paint Profiler 這個工具,Paint Profiler 位於 Chrome DevTools > More tools > Layers,點某一圖層後,在 Details 上會顯示 Paint Profiler 連結,點進去就會看到了。
點進去就看到 Paint Profiler,呈現繪製階段所有的細節。
這些細節可作為簡化繪製複雜度的改進建議,範例。
合成(Composite)
在 Chrome DevTools Timeline 的紀錄中,有兩種是和 Composite 相關的
- Update Layer Tree:發生於 Chrome 內部引擎 Blink 在試圖弄清楚元素的樣式、這個頁面需要哪些圖層、到底有多少圖層、這些圖層的順序是什麼。
- Composite Layers:瀏覽器將這些圖層依序組合起來,輸出至螢幕上。層數愈多,就需要花愈多時間在圖層的管理和合成上。
圖層數太多嗎?該降低圖層數了。
如何提升繪製會和合成的效能?
升階可提升繪製的效能,而圖層數關乎合成的效能,因此這是「減少繪製區域」和「增加圖層數」的取捨。圖層數愈多,就需要花愈多時間在圖層的管理和合成上,但可換得減少繪製區域的好處;圖層數愈少,雖然花在圖層管理和合成的時間較少,但繪製區域範圍較大、較花時間。
範例-概念說明
開發者通常不干涉圖層的管理,基本上都交由瀏覽器自動處理,但若為了減少繪製的區域,就會考慮把某些元素提升到另一個圖層,意即升階,有什麼需要更新的,就處理這一塊就好。
範例如下,這是一個手機版網站,左側是側邊欄,右側上方有一個小的導航列(含漢堡選單和標題),右側下方是文章列區塊。
試著說明哪些元素要放到同一個圖層?針對要放在同一個圖層的元素,標記同一個數字。
圖片來源:Browser Rendering Optimization: Compositing and Painting
防雷-第一次… ヽ(∀ ゚ )人(゚ ∀ ゚)人( ゚ ∀)人(∀ ゚ )人(゚ ∀ ゚)人( ゚ ∀)ノ
…
防雷-第二次… ヽ(∀ ゚ )人(゚ ∀ ゚)人( ゚ ∀)人(∀ ゚ )人(゚ ∀ ゚)人( ゚ ∀)ノ
…
防雷-最後提醒… ヽ(∀ ゚ )人(゚ ∀ ゚)人( ゚ ∀)人(∀ ゚ )人(゚ ∀ ゚)人( ゚ ∀)ノ
…
答案。
Layers
若想知道目前頁面上有多少圖層、產生圖層的原因,可使用 Chrome DevTools > More tools > Layers,可用此控管圖層數目。
左邊的側邊欄顯示有多少圖層和所屬 DOM Element,右上可針對此圖層旋轉或指定圖層,指定後可在右下看 Details 和 Profiler。Details 上的 Compositing Reasons 會顯示產生圖層的原因。
Layout Borders
既然想把元素分圖層管理,那就要先確認想要放在同一層的元素是否擁有自己的圖層。
使用工具 Layout borders 來檢視頁面上的圖層狀態,Layout borders 位於 Chrome DevTools > Rendering > Layout borders,開啟後會看到頁面顯示網格,淺藍色的線表示瀏覽器自行將圖層切割的狀況,橘框表示元素所在的圖層。
will-change
如果想要放在同一個圖層的元素沒有自己的圖層,就提升它們到另一個圖層。建立新圖層的方式,即是在該元素使用 will-change: transform
或舊瀏覽器可用密技(hack) transform: translateZ(0)
。will-change
會提示瀏覽器有視覺上的更動,然後將這些元素放到一個新的合成圖層上,這樣就可以減少繪製的區域,這對於 opacity 或移動效果特別有用。
.layer {
will-change: transform;
transform: translateZ(0);
}
will-change
和 translateZ(0)
的差異在於
will-change
提示瀏覽器提前分配支援,讓這個元素升階,但瀏覽器可選擇忽略。translateZ(0)
強迫瀏覽器升階,瀏覽器是沒有選擇的。
注意,不要為了提升效能,在所有元素都加上 will-change
,因為這會增加記憶體的使用和花更多時間在合成階段上,導致效能不佳,這在手機上尤其明顯。
範例
點此看範例網站。
若要升階元素 .box
,CSS 要怎麼寫呢?
解答。
答案是在 .box
加入 will-change: transform
。
範例-找出產生新圖層的原因?
點此看範例網站,打開 Layers 後點選 section#background
這個圖層。
同上圖,由於 #background
這個元素使用 CSS 3D transform,因此產生新圖層。若拿掉這指令就不會產生新的圖層了。