References

Beginner-friendly references for web development, with live, editable examples.

The JavaScript requestAnimationFrame() method

Method JavaScript All modern browsers Updated
Quick answer

The requestAnimationFrame() method schedules a function to run just before the browser's next repaint, syncing your animation to the display's refresh rate (usually 60fps). For a continuous animation, call it again inside the callback to form a loop. It's far smoother and more efficient than animating with setInterval().

Overview

requestAnimationFrame() (often shortened to rAF) asks the browser to run your function right before it paints the next frame. Because it's tied to the display's refresh cycle, the animation runs as smoothly as the screen allows — typically 60 times a second — and the browser can optimize it, pausing it entirely when the tab is in the background to save battery.

For a one-off, you call it once. For a continuous animation, the pattern is to call requestAnimationFrame() again from inside the callback, creating a self-sustaining loop that runs each frame until you stop it. Your callback receives a high-resolution timestamp, which you use to make movement time-based (so it looks the same regardless of frame rate) rather than tied to a fixed step per frame.

It's the correct replacement for the old habit of animating with setInterval(), which isn't synced to the display, can drop or stack frames, and keeps running in hidden tabs. To stop a rAF loop, save the ID it returns and pass it to cancelAnimationFrame(id). For simple property transitions, plain CSS transitions or animations are even better — reach for rAF when you need JavaScript-driven, frame-by-frame control (canvas, physics, custom easing).

Syntax

const id = requestAnimationFrame(callback);

function loop(timestamp) {
  // update something based on timestamp
  requestAnimationFrame(loop);   // keep going
}
requestAnimationFrame(loop);

cancelAnimationFrame(id);  // stop it

Parameters

The requestAnimationFrame() method accepts the following parameters.

Parameter Description
callback A function to run before the next repaint. It receives a high-resolution timestamp (milliseconds) as its argument.

Example

Live example
<div style="background:#e2e8f0;border-radius:6px;overflow:hidden">
  <div id="bar" style="height:20px;width:0;background:#1c7ce9"></div>
</div>
<p id="out" style="font:14px system-ui"></p>
<script>
  const bar = document.getElementById('bar');
  const start = performance.now();

  function grow(now) {
    const pct = Math.min((now - start) / 2000 * 100, 100); // 2s to fill
    bar.style.width = pct + '%';
    document.getElementById('out').textContent = Math.round(pct) + '%';
    if (pct < 100) requestAnimationFrame(grow);
  }
  requestAnimationFrame(grow);
</script>

Best practices

  • Loop by calling requestAnimationFrame() again inside the callback.
  • Use the timestamp argument for time-based movement, so animation is consistent across frame rates.
  • Prefer it over setInterval() for animation — it syncs to the display and pauses in hidden tabs.
  • Save the returned ID and call cancelAnimationFrame(id) to stop; for simple effects, use CSS transitions instead.

Frequently asked questions

What is requestAnimationFrame used for?
Running a function before each repaint to drive smooth animations synced to the display's refresh rate.
How do I create an animation loop?
Call requestAnimationFrame(loop), and inside loop call requestAnimationFrame(loop) again to schedule the next frame.
Why use requestAnimationFrame instead of setInterval?
rAF syncs to the screen refresh, avoids dropped/stacked frames, and pauses in background tabs — setInterval() does none of those.
How do I stop a requestAnimationFrame loop?
Save the ID it returns and call cancelAnimationFrame(id).