Are you still using setInterval for animating things on your website?
Forget about it! This is what I discovered yesterday. I started to make a simple parallax scrolling and used
setInterval initially.
I was not much convinced with the result, because I encountered some flicker and minor slowdowns. So, I searched for hints
for optimizing my experience and discovered there is some relatively new technique out there called
requestAnimationFrame.
Here is what I've done intially
function ParallaxScroller() {
var that = this;
var layers = [];
this.addLayer = function(layer){
layers.push(layer);
}
this.start(timeout){
setInterval(render, timeout);
}
this.render=function(){
for(var i=0; i<layers.length; ++i){
layers[i].update();
}
}
};
var scroller = new ParallaxScroller();
scroller.addLayer( /* layer */ );
scroller.start(50);
And here is the same code using
requestAnimationFrame
function ParallaxScroller() {
var that = this;
var layers = [];
this.addLayer = function(layer){
layers.push(layer);
}
this.render=function(){
for(var i=0; i<layers.length; ++i){
layers[i].update();
}
requestAnimationFrame(that.render); // # HERE!
}
};
var scroller = new ParallaxScroller();
scroller.addLayer( /* layer */ );
scroller.render();
The thoughtful reader may have noticed, that there is no interval passed to
requestAnimationFrame.
To understand what is happening here, it is vital to know about the essential difference between
requestAnimationFrame and
setInterval:
Using setInterval for animations forces the browser to refresh the screen when the related callback is triggered. That means, screen updates occur at any time, and have a good chance to be unnecessary. As a result the animations can be crude. Using rFA instead overcomes those "update interruptions". As the name says it requests an update frame. So, the browser becomes responsible to decide whether a callback is triggered, or not. Yes, he might decide not to trigger, for example if the updating page is not visible. The browser can synchronize the callback with its own refreshing rate, which is usually 60Hz, to avoid unnecessary (and CPU costly) repaints. Consequently, you get smoother results due to synchronized refreshes and can safe CPU resource (and battery life), especially while the screen is not visible.
That's why I simply do not care about frame rates when animate my stuff on the screen using
rFA. The animations are updated in the correct time slot nearly all 16 ms.
There are other articles out in the wild which explain more precisely how it works, like
"Better performance with requestAnimationFrame",
CreativeJS requestAnimationFrame , and
"Better JavaScript animations with requestAnimationFrame". Also interesting is
"Microsoft's rFA Testdrive", that compares both methods visually.