高性能动画(high-performance-animations)

来源:互联网 发布:阿里云流量计费标准 编辑:程序博客网 时间:2024/04/30 15:39

我们就直接切入正题了。在现代浏览器中,有四个CSS属性实现动画效果的代价很低:position,scale,rotation和opactiy。 如果用其它属性来做动画的话,你就要自己承担风险了,很可能你不会获得如丝般平滑的60fps的动画效果。

让我们通过并排演示一组同样的动画的慢镜头,来看看这两者有什么差异:http://www.youtube.com/watch?feature=player_embedded&v=-62uPWUxgcg

一个是通过transform来实现的,另外一个不是。你能看到有什么影响和不同,下面让我们看看为什么会这样子。

开发工具-从DOM到像素

当你使用Chrome开发工具的时间线时,你会看到类似这样子的图表:

浏览器经历的过程非常简单:计算会应用到元素的样式(Recalculate Style),生成元素的形状和位置(Layout),为每个元素的像素填充到层中(Paint Setup and Paint),最后把层绘制到屏幕(Composite Layers)。

为了获得如丝般平滑的动画效果,我们需要避免让浏览器做大量的工作,最好的方式是仅仅改变影响合成的属性:transform和opacity。时间线中瀑布流越高,浏览器把像素绘制到屏幕需要做的工作就越多。

Paul Irish: 这个建议能够广泛的跨浏览器兼容。Chrome, Firefox, Safari and Opera 等所有硬件加速transforms and opacity的浏览器。不幸的是,还不清楚ie10+ 使用什么标准来确定硬件加速是合适的。

用布局属性做动画

当你改变元素的时候,浏览器可能需要重新布局,这就涉及计算这个变化影响到的所有元素的大小和位置。如果你改变某一个元素,其它元素的几何结构可能页需要重新计算。例如,如果你改变<html>的宽度,它的任何子元素都会被影响。由于元素溢出和相互影响,DOM树的变化有时候又会导致树顶的布局计算

可见树越大,需要执行布局计算的时间越长,因此,你必须尽量避免使用会触发布局的属性来做动画效果。

下面是最常见的在值改变时会触发layout的CSS属性:

用paint属性做动画

改变元素也可能会触发重绘。现代浏览器中的大多数采用软件栅格化来完成绘制的。取决于你的app中元素如何被分组到层里的, 除了改变的这些元素,其它元素也有可能会重绘。

Paul Irish: 如果你对层的概念还不太了解的话,可以阅读Tom Wiltzius的文章

有许多触发paint的元素,下面这些事最常用的:

如果你使用上面的任何一个属性做动画,影响到元素都需要重绘,他们所在的层会被上传到GPU。在移动设备上,这样的成本非常高,因为移动设备上的CPU相对于桌面来说差太多了,这就意味着需要花更长的时间来完成paint。在CPU和GPU之间的带宽也是有限的,因此上传texture会花更长的时间。

用Composite属性做动画

有一个CSS属性你可能认为会引起重绘,实际上却不会:opacity。GPU在合成的时候可以对opacity的改变进行处理,这只需要简单的用一个小的alpha值绘制元素的texture。当然,这个元素必须是层里唯一的元素。如果与其它元素在同一个层里,那么在GPU上改变opacity也一起改变。

在Blink和Webkit浏览上,带有CSS transition或animation 的opacity属性都会创建一个层。但是许多开发者使用translateZ(0)or translate3d(0,0,0)来手动强制创建层。强制层的创建确保动画开始时层被绘制并准备好使用。绘制层不是一个小的操作,它可能会延迟动画的开始;同时确保由于反锯齿的变化外观上没有改变。不管如何,层的创建应该是少量的。如果创建过多的层,可能会导致不流畅

改变元素的transform其实就是改变position,rotation或者scale。position经常采用left和top值来完成动画。这个问题,如上显示,left和top都会触发重绘操作,有很高的成本。更好的解决方式是在元素上使用translate,这个不会触发layout。

命令式和声明式的动画

开发者经常要决定是使用JS(命令式)还是CSS(声明式)来做动画。每种方法都有好处和坏处,让我们来看看。

命令式动画的主要优点碰巧是他的主要缺点:他运行在浏览器主线程中的js。主线程已经忙于JS,样式计算,布局和绘制。经常会出现线程竞争。这实质上会增加失去动画帧的机会,是我们最不愿看到的事情了。

JS动画的确会给你很多控制:开始,暂停,颠倒,中断,取消都是微不足道了。一些效果比如视差滚动只能使用js来完成。

声明式

另外一种方式是用CSS来写你的动画和过渡。主要的好处是浏览器可以优化动画。如果需要,它会创建层,然后运行默写不占用主线程的操作。CSS动画的主要缺点是缺少JS动画的表现力。很难用有意义的放肆混合动画,意味着制作动画比较复杂而且容易出错。

展望

随着web标准的不断发展,一些对动画的限制很快就会消失。Google的Ian Vollick调研了通过workers来完成动画的概念,提供了不触发布局和样式计算的动画。如果你对使用声明式动画感兴趣的话, Jake Archibald 有一个广泛的Web 动画规范

结束语

流畅的动画对于用户体验是非常关键的。你应该要总是避免使用会触发布局或重绘的属性来完成动画效果,他们都是非常危险的,可能会导致丢失帧。声明式的动画优于命令式。

今天,transform是实现动画效果最好的属性,因为GPU能够协助繁重的担子,因此在你可以把动画限制到这些的地方,就一定要这样做。

原文链接:http://www.html5rocks.com/en/tutorials/speed/high-performance-animations/

0 0
原创粉丝点击