關於JS動畫和CSS3動畫的性能差異


本文章為綜合其它資料所得。

 根據Google Developer,Chromium項目里,渲染線程分為main thread和compositor thread。

如果CSS動畫只是改變transformsopacity,這時整個CSS動畫得以在compositor thread完成(而JS動畫則會在main thread執行,然后觸發compositor進行下一步操作)
在JS執行一些昂貴的任務時,main thread繁忙,CSS動畫由於使用了compositor thread可以保持流暢,可參考adobe的博客

在主線程中,維護了一棵Layer樹(LayerTreeHost),管理了TiledLayer,在compositor thread,維護了同樣一顆LayerTreeHostImpl,管理了LayerImpl,這兩棵樹的內容是拷貝關系。因此可以彼此不干擾,當Javascript在main thread操作LayerTreeHost的同時,compositor thread可以用LayerTreeHostImpl做渲染。當Javascript繁忙導致主線程卡住時,合成到屏幕的過程也是流暢的。
為了實現防假死,鼠標鍵盤消息會被首先分發到compositor thread,然后再到main thread。這樣,當main thread繁忙時,compositor thread還是能夠響應一部分消息,例如,鼠標滾動時,加入main thread繁忙,compositor thread也會處理滾動消息,滾動已經被提交的頁面部分(未被提交的部分將被刷白)。

CSS動畫比JS流暢的前提:

  • 在Chromium基礎上的瀏覽器中
  • JS在執行一些昂貴的任務
  • 同時CSS動畫不觸發layout或paint
    在CSS動畫或JS動畫觸發了paint或layout時,需要main thread進行Layer樹的重計算,這時CSS動畫或JS動畫都會阻塞后續操作。

參考CSS Triggers,只有如下屬性的修改才符合“僅觸發Composite,不觸發layout或paint”:

  • backface-visibility
  • opacity
  • perspective
  • perspective-origin
  • transfrom

所以只有用上了3D加速或修改opacity時,才有機會用得上CSS動畫的這一優勢。

因此,在大部分應用場景下,效率角度更值得關注的還是下列問題。

  • 是否導致layout
  • repaint的面積
  • 是否是有高消耗的屬性(css shadow等)
  • 是否啟用硬件加速

那么Chromium以外的其他瀏覽器呢?CSSTrick里比較了一次效率

Animated properties JS-based Animation更快 CSS-based Animation更快
top, left, width, height Windows Surface RT, iPhone 5s (iOS7), iPad 3 (iOS 6), iPad 3 (iOS7), Samsung Galaxy Tab 2, Chrome, Firefox, Safari, Opera, Kindle Fire HD, IE11 (none)
translate, scale Windows Surface RT, iPhone 5s (iOS7), iPad 3 (iOS7), Samsung Galaxy Tab 2, Firefox, Opera, IE11 iPad 3 (iOS6), Safari, Chrome

可以看到,Chromium以外的其他瀏覽器沒有這方面的CSS動畫效率的優化。盡管MSDN提到“它可提供更好的呈現性能”,但測試並沒有支持這一點。


現今CSS動畫和JS動畫主要的不同點是

  • 功能涵蓋面,JS比CSS3大
    • 定義動畫過程的@keyframes不支持遞歸定義,如果有多種類似的動畫過程,需要調節多個參數來生成的話,將會有很大的冗余(比如jQuery Mobile的動畫方案),而JS則天然可以以一套函數實現多個不同的動畫過程
    • 時間尺度上,@keyframes的動畫粒度粗,而JS的動畫粒度控制可以很細
    • CSS3動畫里被支持的時間函數非常少,不夠靈活
    • 以現有的接口,CSS3動畫無法做到支持兩個以上的狀態轉化
  • 實現/重構難度不一,CSS3比JS更簡單,性能調優方向固定
  • 對於幀速表現不好的低版本瀏覽器,CSS3可以做到自然降級,而JS則需要撰寫額外代碼
  • CSS動畫有天然事件支持(TransitionEndAnimationEnd,但是它們都需要針對瀏覽器加前綴),JS則需要自己寫事件
  • CSS3有兼容性問題,而JS大多時候沒有兼容性問題


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM