Posted on by & filed under Content - Highlights and Reviews, Web Development.

When it comes to developing animated applications driven by JavaScript you always depend on some type of loop, one that recalculates the position, color, scaling or other attributes for every frame. This is also a reoccurring problem in other languages and/or frameworks, which work with GUI and animation. The base setup of an openFrameworks application or a processing application has a draw() function that is called for every frame, preferably 60 times a second.

JavaScript in its pure form doesn’t have that. However, over the years developers have used Intervals to accomplish such a loop. An interval can be created by calling the setInterval method and passing a function and an amount of milliseconds. The script will call the function every X milliseconds.

This works just fine for most applications. The problem with this method, however, is that it is time based and may not necessarily call the function in the same interval in which the browser renders or executes JavaScript.

Nevertheless, the best performance can be reached when the JavaScript execution and recalculation of attributes (e.g. styles, position, etc.) is synced up with the browser-internal render cycle.

In order to achieve this, a separate hook was established in modern browsers called requestAnimationFrame. This function is called with the same execution rate as the browser’s rendering. That means it is called right before the browser re-renders the page. Note that this will be called only once, not consecutively. Thus, with every loop, you have to hook into the requestAnimationFrame again.

Unfortunately, this function is not fully standardized, and therefore most browsers use their specific suffix for the function. By using this simple shim you can cover all the different browsers and fall back to using intervals (specifically, a timeout, which is like an Interval but called only once) in case the requestAnimationFrame is not supported:

Embedding this shim at the top of your code allows you to create the fastest, most optimized render loop possible using the requestAnimationFrame:

Not only is the calculation in sync with the rendering of the browser, but also the requestAnimationFrame won’t be invoked when the user switches to another tap. This let’s your animation pause whenever the user is not actively viewing the site, which ultimately means it saves a lot of power.

You can find this snippet of code at

Safari Books Online has the content you need

Check out these JavaScript books available from Safari Books Online:

In Professional: JavaScript for Web Developers, Third Edition Veteran author and JavaScript guru Nicholas Zakas shows how JavaScript works with the new HTML5 as well as other significant advances in web development as it relates to JavaScript.
You may have definite ideas about writing code when working alone, but team development requires that everyone use the same approach. With the JavaScript practices in Maintainable JavaScript—including code style, programming tips, and automation—you’ll learn how to write maintainable code that other team members can easily understand, adapt, and extend.
In Foundation HTML5 Animation with JavaScript is a fantastic resource for all web developers working in HTML5 or switching over from Flash to create standards-compliant games, applications, and animations that will work across all modern browsers and most mobile devices, including iPhones, iPads, and Android devices.

About this author

Mathias Paumgarten, co-author of HTML5 Games Most Wanted, is a web developer who focuses on front-end and interaction development. Starting with a background in Flash development, he now focuses mainly on JavaScript. He found his passion for the web and code-based animation at a very young age and made his way from a small town in Austria all the way to New York City where he currently works for Firstborn Multimedia as a Creative Developer. Part of his work can be found at and

Tags: animated apps, Javascript, requestAnimationFrame,

Comments are closed.