Why requestAnimationFrame Beats setTimeout for Smooth Animations – A Deep Dive
An in‑depth investigation compares requestAnimationFrame and setTimeout for web animations, revealing how the former syncs with browser repaint cycles, why it outperforms setTimeout, the limits of manually adjusting frame rates, compatibility issues across browsers and platforms, and practical fallback implementations.
When developing a WeChat mini‑program I wanted a gravity‑sensor parallax effect, but the platform does not support the HTML5
DeviceOrientationEvent. Instead it provides
wx.onAccelerometerChangeat only 5 Hz, which makes the animation appear choppy because smooth motion requires at least 60 fps.
Differences from setTimeout
MDN defines
requestAnimationFrameas a method that notifies the browser to call a specified function before the next repaint. This raises the question: does the callback run automatically before the repaint, or is it simply called after a fixed interval?
window.requestAnimationFrame() is used to tell the browser to invoke a callback before the next repaint, allowing developers to synchronize animations with the display refresh.
Animations should avoid layout‑changing properties like
leftor
marginand instead use
transform: translate. Even better is
translate3d, which triggers full GPU acceleration.
To verify the behavior, I ran the following code:
<code>var laststart;
function test(){
laststart && console.log(Date.now() - laststart);
laststart = Date.now();
requestAnimationFrame(test);
}
requestAnimationFrame(test);
</code>In Chrome on macOS the repaint frequency was about 60 times per second, as shown below:
I then asked three questions:
Can I artificially increase the repaint frequency?
Does calling
requestAnimationFrameguarantee a certain repaint rate?
If I never call it, will the page ever repaint?
By varying the
setTimeoutinterval (16 ms, 10 ms, 8 ms, 5 ms) and applying a simple translate animation, I observed that the visible flicker speed followed the order
i16 > i10,i5 > i8. The browser always limited repaint to its native ~60 Hz, regardless of how frequently the callback attempted to change styles.
Conclusion: the browser’s repaint frequency cannot be manually overridden; it matches the display’s refresh rate (typically 60 Hz). The only way to influence animation smoothness is to let the browser schedule frames via
requestAnimationFrame.
Compatibility
MDN’s compatibility table shows that
requestAnimationFrameis not supported in older browsers and in the iOS version of WeChat mini‑programs.
Therefore a polyfill is required. Below is a fallback implementation that uses
setTimeoutto approximate a 60 fps schedule when the native API is unavailable.
<code>;(function(){
var lastTime = 0;
var vendors = ['ms','moz','webkit','o'];
for(var x=0; x<vendors.length && !window.requestAnimationFrame; ++x){
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] ||
window[vendors[x]+'CancelRequestAnimationFrame'];
}
if(!window.requestAnimationFrame){
window.requestAnimationFrame = function(callback){
var currTime = Date.now();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function(){ callback(currTime + timeToCall); }, timeToCall);
lastTime = currTime + timeToCall;
return id;
};
}
if(!window.cancelAnimationFrame){
window.cancelAnimationFrame = function(id){ clearTimeout(id); };
}
})();
</code>requestAnimationFrame in WeChat Mini‑Programs
iOS version of WeChat mini‑programs does not support
requestAnimationFrameat all.
Conclusion
requestAnimationFrameand
setTimeoutserve different purposes; the former synchronizes with the browser’s repaint cycle.
Using
translate3dyields better GPU acceleration than plain
translate.
The browser’s maximum repaint frequency is fixed (typically 60 Hz) and cannot be manually increased.
Calling
requestAnimationFrameguarantees a repaint at the browser’s native rate, even if no visual changes occur.
If
requestAnimationFrameis never called and no other code triggers repaints, the page will not repaint.
Qudian (formerly Qufenqi) Technology Team
Technology team focusing on architecture, service-oriented design, top-tier tools, automation platforms, end-to-end development solutions, talent cultivation, and engineer career growth.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.