Skip to main content

What does requestAnimationFrame() do?

Definition

requestAnimationFrame(callback) is a built-in browser API that schedules the callback function to run before the next repaint (before the "screen redraw").


What this means in practice

When the browser is about to repaint the screen (typically ~60 times per second, i.e. every 16.6 ms), it calls your callback from requestAnimationFrame at the optimal moment, so the animation looks as smooth as possible without jank.


Example

javascript
function animate(time) { console.log('Frame at', time, 'ms'); requestAnimationFrame(animate); // request the next frame } requestAnimationFrame(animate);

What happens here:

  • animate is called before every repaint;
  • time is a timestamp (in milliseconds) showing when the frame's repaint actually started (per performance.now()).

How this works under the hood

  1. You call requestAnimationFrame(fn);
  2. The function fn is stored by the browser;
  3. When the browser is ready to draw a new frame (usually after 16 ms), it calls all such functions right before repainting;
  4. After the callback runs, the browser repaints the screen.

If you call requestAnimationFrame() again inside the callback, the animation runs in a loop, frame after frame.


Example: smooth element movement

javascript
const box = document.querySelector('.box'); let start = null; function move(timestamp) { if (!start) start = timestamp; const progress = timestamp - start; box.style.transform = `translateX(${progress / 5}px)`; if (progress < 2000) { // 2 seconds requestAnimationFrame(move); } } requestAnimationFrame(move);

Here the element moves smoothly over 2 seconds. And the browser optimizes calls itself: if the tab isn't visible, requestAnimationFrame pauses so it doesn't waste resources.


Difference from setTimeout / setInterval

CriterionsetTimeout / setIntervalrequestAnimationFrame
FrequencyFixed (for example, every 16 ms)Synchronized with the screen refresh rate
Power usageNot paused in background tabsAutomatically stops when the tab is hidden
SmoothnessCan "stutter" under loadMaximally smooth repainting
UsageTimers, background tasksAnimations, smooth UI updates
Passes a timestampNoYes (performance.now() frame time)

Comparison example

javascript
function moveWithTimeout() { box.style.left = `${parseInt(box.style.left || 0) + 1}px`; setTimeout(moveWithTimeout, 16); } function moveWithRaf() { box.style.left = `${parseInt(box.style.left || 0) + 1}px`; requestAnimationFrame(moveWithRaf); }

setTimeout doesn't account for browser load and can "skip" frames. requestAnimationFrame adapts to the display's refresh rate and is always as smooth as possible.


Canceling a call

If you need to cancel a scheduled frame:

javascript
const id = requestAnimationFrame(step); cancelAnimationFrame(id);

SUMMARY

PropertyDescription
What it doesRuns a callback before the next repaint
When it's calledWhen the browser is ready to draw a new frame (~60 FPS)
Function argumenttimestamp - the frame's start time
ReturnsA frame ID (for cancelAnimationFrame)
Stops automaticallyYes, when the tab is inactive
Task typeA separate queue for visual updates (before rendering)
Ideal forAnimations, smooth transforms, progress bars

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.