gotchajavascriptModeratepending
Gotcha: setTimeout/setInterval timer drift
Viewed 0 times
setTimeoutsetIntervaldriftaccuracyrequestAnimationFrame
Error Messages
Problem
setTimeout and setInterval are not precise. They guarantee a minimum delay, not an exact one. Intervals can drift over time.
Solution
Timers are approximate, not exact:
// setInterval drifts because it doesn't account for execution time
let count = 0;
setInterval(() => {
count++;
heavyWork(); // Takes 50ms
// Next tick is 1000ms after this call STARTS, not ENDS
// So actual interval is 1050ms, drifting over time
}, 1000);
// Self-correcting timer:
function accurateInterval(fn, interval) {
let expected = Date.now() + interval;
function step() {
const drift = Date.now() - expected;
fn();
expected += interval;
setTimeout(step, Math.max(0, interval - drift));
}
setTimeout(step, interval);
}
// For animations, use requestAnimationFrame:
function animate(timestamp) {
updatePosition(timestamp);
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
// Browser throttles timers:
// - Background tabs: minimum 1000ms interval
// - Nested timers (5+ deep): minimum 4ms
// - Low battery: may further throttle
// setInterval drifts because it doesn't account for execution time
let count = 0;
setInterval(() => {
count++;
heavyWork(); // Takes 50ms
// Next tick is 1000ms after this call STARTS, not ENDS
// So actual interval is 1050ms, drifting over time
}, 1000);
// Self-correcting timer:
function accurateInterval(fn, interval) {
let expected = Date.now() + interval;
function step() {
const drift = Date.now() - expected;
fn();
expected += interval;
setTimeout(step, Math.max(0, interval - drift));
}
setTimeout(step, interval);
}
// For animations, use requestAnimationFrame:
function animate(timestamp) {
updatePosition(timestamp);
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
// Browser throttles timers:
// - Background tabs: minimum 1000ms interval
// - Nested timers (5+ deep): minimum 4ms
// - Low battery: may further throttle
Why
JavaScript timers only guarantee minimum delay. The event loop, CPU load, and browser policies affect actual timing.
Revisions (0)
No revisions yet.