Understanding requestAnimationFrame in JavaScript
The window.requestAnimationFrame() method is a dedicated
browser API designed to synchronize JavaScript visual updates and
animations directly with the display’s refresh rate. By scheduling
execution immediately before the browser performs its next repaint, it
eliminates animation stutter, prevents screen tearing, and reduces
unnecessary resource consumption compared to legacy timer-based
approaches like setTimeout and
setInterval.
Synchronizing with Display Refresh Rates
Modern computer displays typically refresh at a rate of 60Hz (60
frames per second), 120Hz, or higher. When creating animations with
legacy timers such as setInterval, callbacks execute at
arbitrary intervals that do not align with the hardware’s refresh cycle.
This mismatch often triggers frame rendering halfway through a screen
refresh cycle, causing visible glitches known as jank or screen
tearing.
requestAnimationFrame solves this by allowing the
browser to dictate the timing. The browser calls the supplied callback
function right before updating the screen, ensuring that each calculated
frame corresponds directly to a single hardware display refresh.
Preventing Redundant Calculations
When using standard timers with intervals set too low (for example,
attempting 100 updates per second on a 60Hz screen), the browser
calculates visual states that are never actually rendered.
requestAnimationFrame automatically matches the execution
frequency to the user’s specific monitor capabilities, guaranteeing that
no processing power is wasted calculating invisible intermediate
frames.
Optimizing Battery and Resource Usage
A major advantage of requestAnimationFrame is its
integration with browser tab visibility:
- Tab Inactivity: If a user navigates to another tab,
minimizes the window, or scrolls the animated element off-screen, the
browser automatically pauses or severely throttles
requestAnimationFrameexecution. - Hardware Efficiency: Because execution halts when the animation is not visible, CPU and GPU loads drop significantly, preserving battery life on mobile devices and laptops.
Alignment with the Browser Rendering Pipeline
During every frame lifecycle, the browser runs through a specific
pipeline: executing JavaScript, calculating styles, computing layout
(reflow), painting pixels, and compositing layers.
requestAnimationFrame callbacks execute at the very start
of this rendering pipeline. This ensures that any DOM modifications or
style calculations made in JavaScript are processed and rendered in a
single, unified pass, preventing layout thrashing and unnecessary
repaints.
Basic Usage Pattern
Implementing a render loop with requestAnimationFrame
involves recursively passing an update function to the API:
function animate(timestamp) {
// Update visual state (e.g., element position, canvas drawing)
element.style.transform = `translateX(${position}px)`;
// Request the next frame
requestAnimationFrame(animate);
}
// Start the animation loop
requestAnimationFrame(animate);The callback function receives a high-precision
DOMHighResTimeStamp indicating the exact time the frame was
scheduled, allowing developers to calculate delta time and build
frame-rate independent animations.