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 | // Use setInterval to continually update every 20ms until told to stop. |
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:
- 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.
- 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
orsetInterval
cannot be throttled to use fewer resources because the browser has no way of knowing that they are only being used for animation. - 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!