requestAnimationFrame (abbreviated as rAF) outperforms setInterval or setTimeout in performance for several key reasons:
1. Browser Optimization
requestAnimationFrame is an API specifically designed for animations. The browser recognizes that the callback requested via this function is for rendering animations, enabling it to optimize animations such as reducing frame rates in inactive tabs or pausing animations when they are off-screen, thereby improving performance and reducing energy consumption.
2. Screen Refresh Rate Synchronization
The frequency at which requestAnimationFrame callbacks execute is typically synchronized with the browser's screen refresh rate. Most screens have a 60Hz refresh rate, meaning the screen refreshes 60 times per second. rAF strives to match this frequency, updating the animation once per screen refresh to create smooth visual effects. In contrast, setInterval and setTimeout lack this mechanism, potentially causing frame drops or animation updates that are out of sync with screen refreshes, leading to unnecessary computations and screen tearing.
3. Reducing Layout and Repaint
When using requestAnimationFrame for animation, the browser can schedule both visual updates and DOM updates within the same rendering cycle, minimizing layout (layout) and repaint (repaint) operations to enhance performance.
4. CPU Energy Saving
When using setInterval or setTimeout, if the interval specified is very short, they continue running even when elements are not visible, unnecessarily consuming CPU resources. requestAnimationFrame intelligently adjusts, pausing animations when the user switches to other tabs or minimizes the window, which helps reduce CPU consumption, especially on mobile devices.
Example
Consider a simple animation example, such as an element sliding left and right. Using setInterval might be implemented as:
javascriptlet position = 0; setInterval(function() { position += 5; element.style.transform = `translateX(${position}px)`; }, 16); // approximately matching a 60Hz refresh rate interval
This code attempts to move the element every 16 milliseconds but lacks synchronization with screen refreshes.
In contrast, using requestAnimationFrame, the code would be:
javascriptlet position = 0; function step() { position += 5; element.style.transform = `translateX(${position}px)`; requestAnimationFrame(step); } requestAnimationFrame(step);
Here, the animation logic synchronizes with the browser's refresh rate, intelligently adjusting execution frequency based on screen refresh conditions.
In summary, requestAnimationFrame provides a more efficient and smoother animation experience, especially for complex or high-performance animations, which is significantly better than using setInterval or setTimeout.