I use following keyframe animation on several elements:
@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; }
On my computer I am getting around 40% CPU usage both in Chrome and Firefox. Is it the current state of animations (nice but not usable for now) or am I missing some magic property?
You can check the following sample with the same animation: http://jsfiddle.net/Nrp6Q/
The fact is that, in most cases, the performance of CSS-based animations is almost the same as JavaScripted animations — in Firefox at least. Some JavaScript-based animation libraries, like GSAP and Velocity. JS, even claim that they are able to achieve better performance than native CSS transitions/animations.
Definition and Usage. The @keyframes rule specifies the animation code. The animation is created by gradually changing from one set of CSS styles to another. During the animation, you can change the set of CSS styles many times.
Used well, CSS animation is an incredibly useful and powerful tool. It can add interest or creative excitement, direct the user's eye, explain something quickly and succinctly, and improve usability. For that reason, recent years have seen more and more animation on sites and in app.
Yes, this is normal because you have several infinite-loop animations on the page. The CPU is therefore continually doing work while these elements are rendered. There is a "magic" property that will significantly cut-down the CPU usage and that is:
transform: translateZ(0);
This will composite the elements into their own layers (by tricking the browser into thinking it will be doing 3D transforms) and the browser should, in most cases, take advantage of GPU acceleration, lessening the burden on the CPU. For me this cut it down by about 20% (almost half).
To read more about this technique take a look at: http://ariya.blogspot.com/2011/07/fluid-animation-with-accelerated.html
Additionally, the more keyframes you have in the animation, the more taxing it will be as well. Just try the animation with the middle keyframe cut out and you will see another substantial (~10-12%) drop in CPU usage.
Lastly, not all properties are equal -- box-shadow is much harder for the browser to animate smoothly than, say, background-color. Leaving all of the keyframes intact but dropping the box-shadow property, using the translateZ(0) trick had my CPU usage hovered at only 10-11%.
As much as it pains me to say this, for infinite-loop animations an animated .gif is going to perform much, much better than CSS3 in the current state of browser animation, especially if you plan for many of them to remain rendered on the page for some time.
Update 2017:
For those still finding their way to this question and answer, translate3d(0, 0, 0)
provides the same benefit as translateZ(0)
, you're just also setting translateX()
and translateY()
at the same time. Please ignore the comment by @Farside as he uses translate3d(X, Y, Z)
in his demo but does not compare it to translate(X, Y)
, which would show that using this technique still makes a significant difference.
According to this question, some people have found better performance across all browsers, especially Chrome, with transform: rotateZ(360deg)
.
One of the possible ways to reduce the load on CPU, is to use a so called null transform hack
, which is often hailed as something of a silver bullet. In many cases it will drastically improve rendering performance in WebKit and Blink browsers like Chrome, Opera and Safari.
The null transform hack basically does two things:
To "force" a browser, simply add one of these CSS properties to the element:
transform: translateZ(0); /* or its friend: */ transform: translate3d(0, 0, 0);
When working with 3D transforms, it's good to have these properties as well to improve the performance:
backface-visibility: hidden; perspective: 1000;
Enabling a hardware acceleration in CSS3 for a lot of objects may slow down performance! Apparently, each null 3D transform creates a new layer. However, force-hacking layer creation may not always be the solution to certain performance bottlenecks on a page. Layer creation techniques can boost page speed, but they come with a cost: they take up memory in system RAM and on the GPU. So even if the GPU does a good job, the transfer of many objects might be a problem so that using GPU acceleration might not be worth it. The cite from W3C:
However, setting up the element in a fresh layer is a relatively expensive operation, which can delay the start of a transform animation by a noticeable fraction of a second.
Moving a few big objects has a higher performance, than moving lots of small items when using 3D-acceleration. So they must be used wisely and you need to make sure that hardware-accelerating your operation will really help the performance of your page, and that a performance bottleneck is not being caused by another operation on your page.
Moreover, a GPU is designed specifically for performing the complex mathematical/geometric calculations, and offloading operations onto the GPU can yield massive power consumption. Obviously, when hardware kicks in, so does the battery of the target device.
will-change
propertyThe progress is not standing on the one place... W3C introduced the will-change
CSS property. To cut the long story short, the will-change
property allows you to inform the browser ahead of time of what kinds of changes you are likely to make to an element, so that it can set up the appropriate optimizations before they're needed.
Here's what they say in the the draft:
The
will-change
property defined in this specification allows an author to declare ahead-of-time what properties are likely to change in the future, so the UA can set up the appropriate optimizations some time before they’re needed. This way, when the actual change happens, the page updates in a snappy manner.
Using will-change
, hinting to the browser about an upcoming transformation can be as simple as adding this rule to the element that you’re expecting to be transformed:
will-change: transform;
When developing for mobile, developers are forced to take the wide array of device constraints into consideration while writing mobile web apps. Browsers are becoming smarter, and sometimes, it's better to leave the decision to the platform itself, instead of overlapping acceleration and forcing the behavior in a hacky-way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With