改進渲染效能範例 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。