CSS 动画与 JavaScript 动画的性能
对众多应用程序而言,动画对提供友好的用户体验有着关键的作用。我们有很多方式生成 web 动画,比如 CSS transition 和 animation 或者基于 JavaScript 的动画(使用 requestAnimationFrame)。
CSS 过渡和动画
- CSS transition 提供了一个简单的方式去创造当前样式与结束状态样式之间的动画,比如一个 button 的普通状态和 hover 状态。
- CSS animation 许开发者去通过一个初始状态属性值集合与最终状态属性值集合创造动画,而不是单单的初始和最终状态。CSS animations 由两部分组成:描述 CSS 动画的样式,以及一组关键帧,表示动画样式的开始和结束状态,以及可能的中间状态。
就性能方面来说,无论通过 CSS animation 还是 transition 创造动画,
requestAnimationFrame
提供了一种用 JavaScript 代码制作动画的高效方式。本方法的回调函数在绘制下一帧之前由浏览器调用。与需要一个延迟参数的 setTimeout 或 setInterval 相比,requestAnimationFrame 效率高得多。开发人员可以在 requestAnimationFrame 回调函数中通过简单地改变元素的样式(或者更新画布绘制,等等)来创建动画。
性能对比:transitions vs requestAnimationFrame
事实上,大多数场景下,基于 CSS 的动画几乎是跟 JavaScript 动画表现一致,
一些基于 Javascript 的动画库,像GSAP和Velocity.JS,甚至声称他们在性能上可以做得比原生 CSS transition/animation 更好。这是可能的,因为在重绘事件发生之前,CSS transition 和 animation 在主的 UI 线程仅仅是重新采集元素的样式,这跟通过 requestAnimationFrame 回调获取重新采集元素样式是一样的,也是在下一次重绘之前触发。假如二者都是在主 UI 线程创建的动画,那它们在性能方面没有差异。
虽然他们在性能之间没有差异,但是仍然认为 CSS 动画是更好的选择。为什么?关键是只要动画涉及的属性不引起 reflow(重新布局),我们可以把采样操作移出主线程。最常见的属性是 CSS transform。如果一个元素被提升为一个 layer,transform 属性动画就可以在 GPU中进行。这意味着更好地性能,特别是在移动设备上。