改進渲染效能範例 2 - Newsticker
22 Jul 2018使用 Newsticker 作為改進渲染效能的範例,以下列出需要改進之處與解法,並附上測試結果。

圖片來源:Browser Rendering – Performance past the first page load
改善前
明顯卡卡和怪怪的。

點此看原始碼和 Demo。
下圖是目前 Timeline 的效能部份。

要改善的地方
- 移除不必要的 DOM Element 操作。
- 從像素管道(Browser Rendering Pipeline)的角度優化程式碼,避免版面配置(Layout)和繪製(Paint)、盡量使用合成(Composite)就好。
- 使用
requestAnimationFrame取代setTimeout或setInterval,讓瀏覽器依照自身狀況優化動畫效能。 - 使用
will-change升階,減少繪製區域,但不可過度使用,以免增加合成階段的負擔。
目標
- 接近 60fps
- 避免 Forced Synchronous Layout(FSL)與 Layout Thrashing
- 減少各階段或函式的執行時間
改善中
本範例沒有 Forced Synchronous Layout(FSL)與 Layout Thrashing 的問題。
繼續往下看。
requestAnimationFrame
使用 requestAnimationFrame 取代 setInterval,讓瀏覽器依照自身狀況優化動畫效能。
點這裡看此功能完整修改。
移除不必要的 DOM Element 操作 + 改用觸發 Composite 的指令
新增和刪除 DOM Element 是主要的效能瓶頸,這一段的畫面更新頻率是 4fps。
$next = $frame.find('.current').next().addClass('current');
$current.removeClass('current').clone().appendTo($frame).remove();
$frame.css('top', startPos + 'px');
使用 transform 改寫。
$frame.css({
transform: `translateY(-${targetHeight}px)`,
});
更新後接近或超過 60fps。

點這裡看此功能完整修改。
will-change
讓合成這個階段的工作,集中在 newsticker 的內容區塊,同時也避免其他區域的繪製連動到這一塊。


- Recaculate Style 是 92 μs
- Update Layer Tree 是 90 μ
- Paint 是 20 μs 應設法避免這個階段
- Composite 是 96 μs
改善方式是在 ui-newsticker 上加上 will-change,即可消除繪製階段、減少合成的成本。

- Recaculate Style 是 0.13 ms
- Update Layer Tree 是 83 μs
- Composite 是 19 μs
點這裡看此功能完整修改。
改善後

點此看原始碼和 Demo。