QuestionsBrowser

requestAnimationFrame

AnimationMediumBrowser

Why animate with requestAnimationFrame instead of setInterval? Run the demo to count frames rendered in ~500ms.

What it tests

Whether you know rAF syncs to the display refresh and pauses in background tabs.

Approach & answer

requestAnimationFrame(callback) schedules the callback to run BEFORE the browser's next repaint, syncing your work to the display's refresh rate (typically ~60fps, but 120fps on high-refresh screens — so never hard-code 16ms). The callback receives a high-resolution timestamp (a DOMHighResTimeStamp) you use to compute elapsed time and make motion frame-rate INDEPENDENT (move by velocity × delta, not a fixed step). Advantages over setInterval/setTimeout for animation: (1) it's aligned to paint, so you never draw more often than the screen updates or land mid-frame (which causes tearing/jank); (2) the browser PAUSES it in background tabs and when the element isn't visible, saving CPU and battery — timers keep firing and waste work; (3) callbacks are batched, so multiple animations share one frame. To animate continuously, call requestAnimationFrame again from inside the callback (a self-scheduling loop); cancel with cancelAnimationFrame(id). For the actual visual change, still mutate transform/opacity so the compositor can handle it. rAF is also the right place to batch DOM reads/writes to avoid layout thrashing. Use it for JS-driven animation and smooth scroll effects; prefer CSS transitions/animations when the movement is declarative.

Use this technique when

JS-driven animation, smooth scroll/parallax, and batching DOM writes — anything that should track the refresh rate.

References

js