Sleek Animations With requestAnimationFrame

In the world of JavaScript, animation has always been a nuisance. We’ve relied on setTimeout and setInterval for longer than we care to recall. We’ve trusted the millisecond intervals to always be hit right on the mark, even though we all knew that in all likelihood the computer would be so busy with something else that it’d miss the mark we set for it. No longer! We will set aside our old ways and look forward to a great and glorious JavaScript animation future through the use of requestAnimationFrame!

The Unsightly History of JavaScript Animation

I may have been exaggerating slightly in that opening paragraph, but you all know you enjoyed it. In any case, the way animation has been done in the past, and is still done by many, is littered with frailties. To understand the flaws, we need to know how animation was done. setInterval and setTimeout were the core means of controlling the time between each frame. These two native functions behave the same way except that setTimeout will run only once, whereas setInterval will run continuously until clearInterval is called. You can see a simple example of how they work below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Use setInterval to continually update every 20ms until told to stop.
var intervalID;
function animate() {
// animate something

// if done:
clearInterval(intervalID);
}
intervalID = setInterval(animate, 20);

// Use setTimeout to pseudo-recursively do something every 20ms
function animate() {
// if not done:
setTimeout(animate, 20);

// animate something
}
animate();

Overall, there’s nothing wrong with this and it has served us well enough throughout the years. There are several issues with these methods though:

  1. You can’t rely on the number of milliseconds you set to be exact. If your application is very time-sensitive, then you need some special tricks to keep things within an acceptable level of tolerance.
  2. These methods are explicitly used for animation, so the browser, CPU, and GPU can’t optimize them for animation. For example, a background tab/window utilizing setTimeout or setInterval cannot be throttled to use fewer resources because the browser has no way of knowing that they are only being used for animation.
  3. They don’t synchronize with the browser’s built in rendering frames, so the CPU is used more while trying to redrawing both your animation and the entire screen.

The Promising Future of JavaScript Animation

It wasn’t so long ago that Mozilla devised a solution to all of the above problems and they called it requestAnimationFrame. Soon afterward Chrome and Safari picked up the new method. IE will have this soon too. Sadly, they’re each using their vendor prefixes, but a polyfill has been created to assist browsers that don’t have requestAnimationFrame and to eliminate the need for the prefixes.

Essentially you can just replace setTimeout directly with requestAnimationFrame and skip the interval argument and your code will work. The only difference between the two is that instead of waiting a desired number of milliseconds, you will wait until the browser is ready to redraw the screen again. The frequency of redraws is almost always 60 frames per second (16.66ms) and synchronizes with most computer monitors, which greatly optimizes the timing for everything, which saves the computer from doing all the extra work when it’s not ready to redraw a frame. Another upside is that the browser is in control of when an animation frame is ready, so they can throttle the number of frames per second on background tabs to save some CPU cycles and battery life.

Final Frame

I didn’t get much into the details of using requestAnimationFrame, did I? Well, that’s partially because I like to keep the posts a little more on the short side (which I’m sure you slow readers out there enjoy), but the biggest reason is that I’m planning on doing a video tutorial next week to walk you through some techniques you can use with requestAnimationFrame. In the meantime, you can waste some time reading the spec, or play with this jsFiddle that shows a little of what can be done with requestAnimationFrame. Happy Coding!

Author: Joe Zimmerman

Author: Joe Zimmerman Joe Zimmerman has been doing web development ever since he found an HTML book on his dad's shelf when he was 12. Since then, JavaScript has grown in popularity and he has become passionate about it. He also loves to teach others though his blog and other popular blogs. When he's not writing code, he's spending time with his wife and children and leading them in God's Word.