简体   繁体   English

改善CSS3背景位置动画的性能

[英]Improve CSS3 background-position animation's performance

I'm trying to improve a CSS3 animation as it seems the current code is causing some excessive CPU load and the browser seems to be laggy. 我正在尝试改进CSS3动画,因为当前代码似乎导致一些过多的CPU负载,并且浏览器似乎有点滞后。

What can I do? 我能做什么? I've got all the vendor prefixes etc. I'm not sure I can improve the code or refactor it to use it as best code practices. 我有所有的供应商前缀等。我不确定我可以改进代码或重构它以使用它作为最佳代码实践。

Fiddle Demo 小提琴演示

 .wrapper { width: 960px; height: 140px; margin-top: 80px; position: relative; } .content:before { position: absolute; z-index: 1; top: 0; left: 0; width: 100%; height: 100%; content: ""; -webkit-transform: translateZ(0); transform: translateZ(0); -webkit-transform-origin: 50% 50% 0; -ms-transform-origin: 50% 50% 0; transform-origin: 50% 50% 0; v -webkit-animation-name: sideupscroll; animation-name: sideupscroll; /*animation-duration*/ -webkit-animation-duration: 80s; animation-duration: 80s; /*animation-timing-function*/ -webkit-animation-timing-function: linear; animation-timing-function: linear; /*animation-iteration-count*/ -webkit-animation-iteration-count: infinite; animation-iteration-count: infinite; background: url("http://i.imgur.com/wNna7D3.png") repeat fixed 0 0 indigo; -webkit-animation-fill-mode: both; animation-fill-mode: both; } /* Safari and Chrome */ @-webkit-keyframes sideupscroll { 0% { background-position: 0 0; } 50% { background-position: -50% -100%; } 100% { background-position: -100% -200%; } } @keyframes sideupscroll { 0% { background-position: 0 0; } 50% { background-position: -50% -100%; } 100% { background-position: -100% -200%; } } 
 <div class="wrapper"> <div class="content"></div> </div> 

Reason 原因

Animating the background-position of an element is always going to be resource intensive and it has a high probability of causing laggy animations in almost all browsers. 动画元素的background-position始终是资源密集型的,并且几乎在所有浏览器中都很可能导致延迟动画。 This is because, a change to the background-position results in a repaint + a composition in all browsers (+ it also results in re-layout in Webkit). 这是因为,对background-position的更改会导致所有浏览器中的重绘+组合(+它还会导致Webkit中的重新布局)。 Because of the need to perform so many costly operations, the result is always laggy. 由于需要执行如此多的昂贵操作,结果始终是滞后的。

Snippet with problem: 有问题的片段:

The below snippet is the same as your fiddle (without vendor prefixes). 以下代码段与您的小提琴相同(没有供应商前缀)。 Run this snippet and inspect it using Chrome Dev tools after enabling "Show Paint Rects" option. 启用“Show Paint Rects”选项后,运行此代码段并使用Chrome Dev工具进行检查。 You would see a red or green color box on top of the element (this is the paint rect) and the box will either keep blinking constantly or stay colored for the entire duration of the animation. 你会在元素的顶部看到一个红色或绿色的颜色框(这是画颜料矩形),并且该框将持续闪烁或在动画的整个持续时间内保持颜色。 It indicates that a repaint is happening often and thus it impacts performance. 它表明经常发生重绘,因此会影响性能。

In Firefox, the paint rects can be seen by enabling nglayout.debug.paint_flashing in about:config page (set it to true). 在Firefox中,可以通过在about:config页面中启用nglayout.debug.paint_flashing来看到paint rects(将其设置为true)。

 .wrapper { width: 960px; height: 140px; margin-top: 80px; position: relative; } .content:before { position: absolute; z-index: 1; top: 0; left: 0; width: 100%; height: 100%; content: ""; transform: translateZ(0); transform-origin: 50% 50% 0; animation-name: sideupscroll; animation-duration: 80s; animation-timing-function: linear; animation-iteration-count: infinite; background: url("http://i.imgur.com/wNna7D3.png") repeat fixed 0 0 indigo; animation-fill-mode: both; } @keyframes sideupscroll { 0% { background-position: 0 0; } 50% { background-position: -50% -100%; } 100% { background-position: -100% -200%; } } 
 <div class="wrapper"> <div class="content"></div> </div> 


Solution

It is always better to avoid animating the background-* properties (all of which are visual properties) and use properties like transform . 最好避免动画background-*属性(所有这些都是视觉属性)并使用像transform这样的属性。 Using transform produces better performance atleast in Blink (Chrome) and EdgeHTML as Blink only does a re-composition while EdgeHTML triggers a re-layout only for the first time (1st update within animation). 使用transform 在Blink(Chrome)和EdgeHTML中至少可以产生更好的性能,因为Blink只进行重新组合,而EdgeHTML仅首次触发重新布局(动画中的第一次更新)。

Snippet without problem: (or atleast much lesser impact on performance in Blink and EdgeHTML) 片段没有问题:(或至少对Blink和EdgeHTML中的性能影响小得多)

The below snippet uses transform property ( translateX and translateY ) to achieve what is very similar to your expected output (but not the same). 下面的代码片段使用transform属性( translateXtranslateY )来实现与预期输出非常相似的内容(但不一样)。 If you inspect this snippet with dev tools, you'd see that the green box (paint rect) appears only once at the start of the animation. 如果使用开发工具检查此片段,您会看到绿色框(绘制矩形)仅在动画开始时出现一次。 Post that, the browsers only perform compositing and hence the performance is much better. 发布,浏览器只执行合成,因此性能要好得多。

 .wrapper { width: 960px; height: 140px; margin-top: 80px; position: relative; overflow: hidden; } .content:before { position: absolute; z-index: 1; top: 0; left: 0; width: 200%; height: 400%; content: ""; background: url("http://i.imgur.com/wNna7D3.png") 0 0 indigo; background-repeat: repeat; } .content { position: relative; height: 100%; width: 100%; animation-name: sideupscroll; animation-duration: 80s; animation-timing-function: linear; animation-iteration-count: infinite; animation-fill-mode: both; } @keyframes sideupscroll { 0% { transform: translateX(0%) translateY(0%); } 50% { transform: translateX(-50%) translateY(-100%); } 100% { transform: translateX(-100%) translateY(-200%); } } 
 <div class="wrapper"> <div class="content"></div> </div> 

What about Gecko and Webkit? Gecko和Webkit怎么样?

Unfortunately there doesn't to be a solution for browsers using these rendering engines as at the time of writing. 不幸的是,在撰写本文时,使用这些渲染引擎的浏览器并没有解决方案。 The only option seems to be to reduce the animation-duration . 唯一的选择似乎是减少animation-duration A reduction in animation's duration means that the no. 动画持续时间的减少意味着没有。 of re-paint + re-layout + re-composition cycles required is lesser and thus the animation's performance is better. 重新绘制+重新布局+所需的重新组合周期较少,因此动画的表现更好。

The below snippet looks less laggy in Firefox as the duration is only 20s. 下面的代码片段在Firefox中看起来不那么滞后,因为持续时间只有20秒。

 .wrapper { width: 960px; height: 140px; margin-top: 80px; position: relative; overflow: hidden; } .content:before { position: absolute; z-index: 1; top: 0; left: 0; width: 200%; height: 400%; content: ""; background: url("http://i.imgur.com/wNna7D3.png") 0 0 indigo; background-repeat: repeat; } .content { position: relative; height: 100%; width: 100%; animation-name: sideupscroll; animation-duration: 20s; animation-timing-function: linear; animation-iteration-count: infinite; animation-fill-mode: both; } @keyframes sideupscroll { 0% { transform: translateX(0%) translateY(0%); } 50% { transform: translateX(-50%) translateY(-100%); } 100% { transform: translateX(-100%) translateY(-200%); } } 
 <div class="wrapper"> <div class="content"></div> </div> 

Useful Links: 有用的链接:

Note: As I had already stated above, the animation is not 100% the same as what you had in question but in my opinion this is about the closest you could get. 注意:正如我上面已经说过的那样,动画并不是100%与你所讨论的相同,但在我看来这是你能得到的最接近的动画。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM