update fps to use window.requestAnimationFrame

What’s wrong with setTimeout and setInterval?

OK, you’ve done this a million times before. What’s wrong with this picture? Well, a few things. Firstly, setTimeout doesn’t take into account what else is happening in the browser. The page could be hidden behind a tab, hogging your CPU when it doesn’t need to, or the animation itself could have been scrolled off the page making the update call again unnecessary. Chrome does throttle setInterval and setTimeout to 1fps in hidden tabs, but this isn’t to be relied upon for all browsers.

Secondly, setTimeout only updates the screen when it wants to, not when the computer is able to. That means your poor browser has to juggle redrawing the animation whilst redrawing the whole screen, and if your animation frame rate is not in synchronised with the redrawing of your screen, it could take up more processing power. That means higher CPU usage and your computer’s fan kicking in, or draining the battery on your mobile device. Nicolas Zakas does an excellent job explaining the impact timer resolution has on animation in a related article.

Another consideration is the animation of multiple elements at once. One way to approach this is to place all animation logic in one interval with the understanding that animation calls may be running even though a particular element may not require any animation for the current frame. The alternative is to use separate intervals. The problem with this approach is that each time you move something on screen, your browser has to repaint the screen. This is wasteful!

requestAnimationFrame to the rescue!

To overcome these efficiency problems, Mozilla (makers of Firefox) proposed the requestAnimationFrame function, which was later adopted and improved by the WebKit team (Chrome and Safari). It provides a native API for running any type of animation in the browser, be it using DOM elements, CSS, canvas, WebGL or anything else.

What’s wrong with setTimeout and setInterval?

OK, you’ve done this a million times before. What’s wrong with this picture? Well, a few things. Firstly, setTimeout doesn’t take into account what else is happening in the browser. The page could be hidden behind a tab, hogging your CPU when it doesn’t need to, or the animation itself could have been scrolled off the page making the update call again unnecessary. Chrome does throttle setInterval and setTimeout to 1fps in hidden tabs, but this isn’t to be relied upon for all browsers.

Secondly, setTimeout only updates the screen when it wants to, not when the computer is able to. That means your poor browser has to juggle redrawing the animation whilst redrawing the whole screen, and if your animation frame rate is not in synchronised with the redrawing of your screen, it could take up more processing power. That means higher CPU usage and your computer’s fan kicking in, or draining the battery on your mobile device. Nicolas Zakas does an excellent job explaining the impact timer resolution has on animation in a related article.

Another consideration is the animation of multiple elements at once. One way to approach this is to place all animation logic in one interval with the understanding that animation calls may be running even though a particular element may not require any animation for the current frame. The alternative is to use separate intervals. The problem with this approach is that each time you move something on screen, your browser has to repaint the screen. This is wasteful!

requestAnimationFrame to the rescue!

To overcome these efficiency problems, Mozilla (makers of Firefox) proposed the requestAnimationFrame function, which was later adopted and improved by the WebKit team (Chrome and Safari). It provides a native API for running any type of animation in the browser, be it using DOM elements, CSS, canvas, WebGL or anything else.