How to Guarantee Smooth Animations in JavaScript
Written by Flore | Full Stack Product Engineer
The browser API has a magical function to help you achieve 60 fps when you animate your HTML: requestAnimationFrame
. This is a demonstration of what it does, and why you should prefer it to timer functions.
requestAnimationFrame
takes a callback as an argument. This callback should contain the animating code, with a minimum amount of computation –when you request a frame, you’re ready to use it! In exchange, the browser will trigger the callback right before painting a new frame, when it works best with the browser’s own routine, guaranteeing a smooth animation.
For most browsers, you can get up to 60 callbacks per second. In practice, it means that you can call requestAnimationFrame
as many times as you want and the queue of functions will empty at about a rate of 60 callbacks per second.
The callback is called with one argument: the timestamp, in milliseconds, when it gets called. This allows you, for instance, to know how long your animation has been running for.
When to use it
Every time your code is going to perform an animation. The key is to not only call requestAnimationFrame
just once, but every time you need a repaint. Otherwise, you won’t get many of the benefits from it.
Here’s a simple example, triggering an animation on click:
As long as the disc is not positioned on the right side of the box, it keeps moving.
See how all the frames are nicely regular, and the CPU’s resources are consumed in a regular way:
Overall, you can reproduce this behaviour with timing functions, such as setInterval
. It will kind of work, but if your app computes things in the middle of it all, you will soon get jank.
See this second example, using setInterval
:
And here are the frames and CPU profile from the dev tools:
When you launch the example, you probably don’t see any difference. However, you can notice that some frames are missed.
With a timer function, since we force the animation to run when it is convenient for us rather than for the browser, we’re never safe from surprises like that!
Browser Support
This function is very well supported, both on mobile and desktop, meaning that you can count on all the evergreen browsers, as well as Opera and IE10.
Caveat
Your callback will not run if your website is in a background tab, in order to protect the battery life of the user’s phone.