Do you want smooth JavaScript animation?
Creating animation in the JavaScript is simple. Most devs likely have used either setInterval()
or setTimeout()
functions.
function draw() {
// Drawing code goes here
}
setInterval(draw, 100);
function draw() {
setTimeout(draw, 100);
// Drawing code goes here
}
draw();
Both are actually a great choice. It will execute every millisecond. You can perform a repainting on each execution.
Hmm… How about if you have a monitor with a 60Hz refresh rate, and you want to achieve 60 FPS?
You have about 16.7 milliseconds (1000 / 60) to execute your animation code to render each frame.
It's a good idea to perform the event with an FPS calculation.
const frameDuration = 1/60 * 1000; // 60 fps
const slideSomeMore = function( moved ) {
let next = window.performance.now() + frameDuration;
while ( '<Animation Condiontion>' ) {
if ( window.performance.now() < next ) {
continue;
}
// Drawing code goes here
setTimeout( () => slideSomeMore( moved ), 0 );
return;
}
}
slideSomeMore( 0 );
Logically, the above code is perfectly fine. You've done these millions of time before.
Okay, let's see the performance of CPU and Memory usage in the screenshot.
It's quite high, right?
Okay, let's see the timeline
The setTimeout()
takes a long time to complete the recursive function. It happened until the animation gets completed.
Another problem with this approach is, if you see the mid of the animation, the previous cycle is being busy, the current cycle is added up in the execution and the next cycle is going to be delayed!
Yes, you will be ended up having poor performance in delayed/slow animation along with high CPU and memory usage.
What's the solution??
requestAnimationFrame is the Saviour
requestAnimationFrame()
is a specialized looping function created for running animations efficiently instead of event loop (setTimeout() or setInterval()) in the browser. And the result is smoother and more accurate.
It is a relatively recent browser API which is a specialized enqueueing function created for running animations efficiently in the browser.
requestAnimationFrame() always tries to get as close to this magic 60 FPS value as possible. Sometimes, it isn't possible if you have a really complex animation, and if you are running it on a slow computer, your frame rate will be less. In all cases, requestAnimationFrame() will always do the best it can with what it has available.
It is very CPU-friendly, causing animations to stop if the current window or tab is not visible. And battery savings, browsers also implemented throttling for those events, allowing max 1 execution per second.
Using requestAnimationFrame the browser can further optimize the resource consumption and make the animations smoother.
Sounds great! Are there any cons using requestAnimationFrame()?
Well, not exactly. Because this is a new API Microsoft supports requestAnimationFrame
from version 10 of Internet Explorer. Here are the supported browsers to use this API function.
Do you want to know more about requestAnimationFrame? Here Lilli Thompson in Google I/O explaining the requestAnimationFrame in detail. Start the video at 48:04
Happy coding!
Top comments (1)
+1 for the requestAnimationFrame reference.
However, this is not a new API. It was first released in Chrome 22 (per your screenshot), which came out in 2012.