How to Guarantee Smooth Animations in JavaScript

Marfeel Labs
Marfeel Labs
Published in
3 min readAug 3, 2018

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:

Browser dev tools view of the frames and CPU usage with requestAnimationFrame

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:

Browser dev tools view of the frames and CPU usage without requestAnimationFrame

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.

--

--

Marfeel Labs
Marfeel Labs

Discover Marfeel's engineering and tech culture | Systems architecture | Web development | Java | JS | CSS | UX