CSS关键帧animationCPU使用率高,应该是这样吗?

我在几个元素上使用以下关键帧animation:

@keyframes redPulse { from { background-color: #bc330d; box-shadow: 0 0 9px #333; } 50% { background-color: #e33100; box-shadow: 0 0 18px #e33100; } to { background-color: #bc330d; box-shadow: 0 0 9px #333; } } @-webkit-keyframes redPulse { from { background-color: #bc330d; box-shadow: 0 0 9px #333; } 50% { background-color: #e33100; box-shadow: 0 0 18px #e33100; } to { background-color: #bc330d; box-shadow: 0 0 9px #333; } } .event_indicator { display: inline-block; background-color: red; width: 5px; margin-right: 5px; -webkit-animation-name: redPulse; -webkit-animation-duration: 1s; -webkit-animation-iteration-count: infinite; animation-name: redPulse; animation-duration: 1s; animation-iteration-count: infinite; } 

在我的电脑上,我在Chrome和Firefox上占用了40%左右的CPU使用量。 是目前的animation状态(好,但现在不可用)还是我错过了一些神奇的属性?

您可以使用相同的animation检查以下示例: http : //jsfiddle.net/Nrp6Q/

是的,这是正常的,因为你在页面上有几个无限循环animation。 因此CPU在渲染这些元素的过程中不断地做着工作。 有一个“魔术”的属性,将大大削减CPU使用率,即:

 transform: translateZ(0); 

这将把这些元素组合到他们自己的层中(通过欺骗浏览器,使其认为它将进行3D转换),并且在大多数情况下,浏览器应该利用GPU加速,减轻CPU的负担。 对我来说,这个减less了大约20%(差不多一半)。

要了解更多关于这种技术,请看: http : //ariya.blogspot.com/2011/07/fluid-animation-with-accelerated.html

另外,animation中的关键帧越多,效果越好。 只要尝试删除中间关键帧的animation,您将看到另一个大幅(〜10-12%)的CPU使用率下降。

最后,并不是所有的属性都是相同的 – 对于浏览器而言,box-shadow比使用background-color更难。 离开所有的关键帧,但删除了box-shadow属性,使用translateZ(0)技巧,我的CPU使用率只有10-11%的徘徊。

尽pipe这样说很痛苦,但对于无限循环animation来说,animation的.gif在浏览器animation的当前状态中要比CSS3执行得更好,特别是如果您计划将其中的许多保留在页面了一段时间。

2017年更新:

对于那些仍在寻找答案的人来说, translate3d(0, 0, 0)提供了与translateZ(0)相同的好处,您还可以同时设置translateX()translateY() 。 请忽略@Farside的评论,因为他在演示中使用translate3d(X, Y, Z) ,但不会将其与translate(X, Y)进行比较,这表明使用此技术仍然会产生显着的差异。

根据这个问题 ,有些人在所有的浏览器,尤其是Chrome浏览器上都find了更好的性能transform: rotateZ(360deg)

减lessCPU负担的一种可能的方法是使用所谓的null transform hack ,这通常被誉为银弹 。 在很多情况下,它将显着提高WebKit和Blink浏览器(如Chrome,Opera和Safari)的渲染性能。

使用“空变换黑客”(一种硬件合成模式)

空变换hack基本上做了两件事:

  1. 它打开硬件合成模式 (假设它支持平台)
  2. 它创build了一个具有自己背面的新图层

要“强制”浏览器,只需将这些CSS属性中的一个添加到元素中即可:

 transform: translateZ(0); /* or its friend: */ transform: translate3d(0, 0, 0); 

在使用3D变换时,最好也有这些属性来提高性能 :

 backface-visibility: hidden; perspective: 1000; 

“零变换黑客”的注意事项

在CSS3中为许多对象启用硬件加速可能会降低性能! 显然,每个空3D转换创build一个新的层。 但是,强制破解层创build可能并不总是解决某个页面上某些性能瓶颈问题的方法。 层创build技术可以提高页面速度,但是它们带来了成本:它们占用系统RAM和GPU中的内存。 所以,即使GPU做得很好,许多对象的传输可能是一个问题,所以使用GPU加速可能不值得。 W3C的引用:

但是,在新层中设置元素是一个相对昂贵的操作,它可以将变换animation的开始延迟一小段时间。

移动一些大物体比使用3D加速移动大量小物体的性能要高。 所以他们必须明智地使用 ,你需要确保硬件加速你的操作将真正帮助你的页面的性能,而性能瓶颈不是由您的网页上的其他操作造成的。

而且,GPU是专门为执行复杂的math/几何计算而devise的,而在GPU上卸载操作会产生巨大的功耗 。 显然,当硬件投入时,目标设备的电池也是如此。

现代的方式: will-change财产

W3C推出了will-change CSS属性。 简而言之, will-change属性允许您提前通知浏览器您可能对元素进行哪些更改,以便在需要之前设置适当的优化。

以下是他们在草案中所说的内容:

本规范中定义的will-change属性允许作者提前声明哪些属性可能在将来发生变化,所以UA可以在需要之前一段时间设置适当的优化。 这样,当实际的变化发生时,页面以快速的方式更新。

使用will-change ,向浏览器暗示即将到来的转换可以像将规则添加到您期望转换的元素一样简单:

 will-change: transform; 

在开发移动应用程序时,开发人员在编写移动Web应用程序时,不得不考虑各种各样的设备约束条件。 浏览器变得越来越聪明,有时候,最好是把决定权交给平台本身,而不是重叠加速和强行行为。

使用CSS3animation处理某些元素时,我也遇到了类似的高CPU占用情况。 我在animation7个元素的“左”属性,在整个页面中使用了一些不透明和阴影属性。 我决定切换到jQuery.animate,可悲的是没有提高性能。 我的CPU(i7)仍然在9-15%左右,同时显示页面,几个技巧(translateZ等)也没有真正提高性能 – 当我的布局搞砸了(一些绝对定位的元素,哎哟!)。

然后我偶然发现了这个美妙的扩展: http : //playground.benbarnett.net/jquery-animate-enhanced/

我只是简单地引用了.js文件,并没有对jQuery过渡做一个单独的修改,而且我的CPU使用率现在在同一页面上只有1-2%。

我的build议:当使用CSS3转换面对CPU问题时,切换到jQuery +animation增强插件。

你也可以在你想使用GPU而不是CPU的任何下列类中使用它

 .no-cpu { transform: translateZ(0); -webkit-transform: translateZ(0); -ms-transform: translateZ(0); } <element class="event_indicator no-cpu">animation...</element >