Animations are critical for a pleasurable user experience on many applications. There are many ways to implement web animations, such as CSS
CSS transitions and animations
Both CSS transitions and animations can be used to write animation. They each have their own user scenarios:
transitionsprovide an easy way to make animations occur between the current style and an end CSS state, e.g., a resting button state and a hover state. Even if an element is in the middle of a transition, the new transition starts from the current style immediately instead of jumping to the end CSS state. See Using CSS transitions for more details.
animations, on the other hand, allow developers to make animations between a set of starting property values and a final set rather than between two states. CSS animations consist of two components: a style describing the CSS animation, and a set of key frames that indicate the start and end states of the animation's style, as well as possible intermediate points. See Using CSS animations for more details.
In terms of performance, there is no difference between implementing an animation with CSS transitions or animations. Both of them are classified under the same CSS-based umbrella in this article.
setInterval(), which need a specific delay parameter,
requestAnimationFrame() is much more efficient. Developers can create an animation by simply changing an element's style each time the loop is called (or updating the Canvas draw, or whatever.)
Note: Like CSS transitions and animations,
requestAnimationFrame() pauses when the current tab is pushed into the background.
transitions vs. requestAnimationFrame
requestAnimationFrame() callback, also triggered before the next repaint. If both animations are made in the main UI thread, there is no difference performance-wise.
In this section we'll walk you through a performance test, using Firefox, to see what animation method seems better overall.
Enabling FPS tools
Before going through the example, please enable FPS tools first to see the current frame rate:
- In the URL bar, enter about:config; click the I’ll be careful, I promise! button to enter the config screen.
- In the search bar, search for the
- Double-click the entry to set the value to
true. Now you will be able to see three little purple boxes at the upper left corner of the Firefox window. The first box represents FPS.
Running the performance test
Initially in the test seen below, a total of 1000
<div> elements are transformed by CSS animation.
The animation can be switched to
requestAnimationFrame() by clicking the toggle button.
Try running them both now, comparing the FPS for each (the first purple box.) You should see that the performance of CSS animations and
requestAnimationFrame() are very close.
Off main thread animation
Even given the test results above, we'd argue that CSS animations are the better choice. But how? The key is that as long as the properties we want to animate do not trigger reflow/repaint (read CSS triggers for more information), we can move those sampling operations out of the main thread. The most common property is the CSS transform. If an element is promoted as a layer, animating transform properties can be done in the GPU, meaning better performance/efficiency, especially on mobile. Find out more details in OffMainThreadCompositing.
To enable the OMTA (Off Main Thread Animation) in Firefox, you can go to about:config and search for the
layers.offmainthreadcomposition.async-animations. Toggle its value to
After enabling OMTA, try running the above test again. You should see that the FPS of the CSS animations will now be significantly higher.
Note: In Nightly/Developer Edition, you should see that OMTA is enabled by default, so you might have to do the tests the other way around (test with it enabled first, then disable to test without OMTA.)