Glossary / Animation frame callbacks

Animation frame callbacks

requestAnimationFrame(callback) asks the browser to run a callback before a future repaint, making it the preferred scheduler for visual updates driven by JavaScript. It is one-shot: request another frame inside the callback to continue an animation. The callback receives a high-resolution timestamp that should drive progress so animation speed is independent of display refresh rate.

Frame-based updates

let previous;
function animate(timestamp) {
  if (previous !== undefined) update((timestamp - previous) / 1000);
  previous = timestamp;
  requestAnimationFrame(animate);
}
requestAnimationFrame(animate);

Displays refresh at different rates (60, 120, 144 Hz and others), so advancing by a fixed amount per callback makes animation run faster on high-refresh screens. Use elapsed time and cap unusually large deltas after background suspension if needed. Browsers commonly pause rAF in hidden tabs/iframes to save resources; animation state should tolerate that.

Use rAF to batch DOM reads/writes near paint, but avoid layout thrashing by separating measurement and mutation. It does not move CPU work off the main thread; expensive callbacks still block rendering. Cancel with cancelAnimationFrame(id) when the animation owner is disposed. For nonvisual background tasks use another scheduling strategy.

Interview questions

  1. Why use rAF instead of setInterval for animation? It aligns visual work with repaint and avoids fixed-rate mismatch.
  2. Is rAF repeating? No; request another frame in the callback.
  3. How make motion refresh-rate independent? Use the callback timestamp/delta.
  4. Does rAF run in hidden tabs? It is commonly paused or throttled; do not rely on it for background timing.

References