The primary difference between (rAF) and (rIC) is priority and timing within the browser's event loop.
Key Differences
| Feature | (rAF) | (rIC) |
|---|---|---|
| Priority | High: Critical for visual updates. | Low: Non-critical background tasks. |
| Timing | Executes before the next repaint/refresh. | Executes during idle periods at the end of a frame. |
| Frequency | Matches display refresh rate (usually 60Hz). | Unpredictable; depends on CPU availability. |
| Best For | Animations, UI transitions, and DOM changes. | Analytics, background data processing, or logging. |
| Browser Support | Universal support across all modern browsers. | Not supported in Safari; experimental in others. |
Detailed Comparison
requestAnimationFrame
• Synchronization: It synchronizes your code with the browser's V-Sync, ensuring that visual changes happen exactly once per frame to prevent "jank" or screen tearing.
• Power Efficiency: If the tab is backgrounded or hidden, the browser automatically pauses rAF calls to save battery and CPU.
• Usage: Ideal for any task that modifies the DOM or CSS styles for visual feedback.
requestIdleCallback
• Idle Deadline: It provides a object with a method, allowing you to check how many milliseconds are left before the browser needs to process higher-priority tasks.
• Guaranteed Execution: You can pass an optional (e.g., ) to force the browser to run the task even if it never becomes idle.
• Restrictions: You should not modify the DOM inside rIC, as it occurs after the frame's layout and paint phases; doing so can cause expensive reflows in the next frame.
When to use which?
• Use requestAnimationFrame when you need to update the UI or perform an animation.
• Use requestIdleCallback for background tasks like sending telemetry, pre-fetching data, or non-urgent state calculations that shouldn't interrupt user interaction.
rAF, rIC and Deferred Value
Use requestAnimationFrame (rAF) or requestIdleCallback (rIC) serve different performance goals compared to the built-in useDeferredValue hook. [1]
Choosing the Right API
• requestAnimationFrame (rAF): Best for visual synchronization. It ensures the value updates just before the next browser repaint (typically every 16.67ms), preventing visual stuttering during high-frequency updates like scrolling or resizing.
• requestIdleCallback (rIC): Best for non-urgent background work. It waits until the browser is completely idle before updating the value, which avoids interfering with critical user interactions like typing.
• useDeferredValue (React Built-in): If you are on React 18+, this is usually superior because it integrates with React's Concurrent Mode. It schedules a low-priority background render that is interruptible if a new update occurs. [2, 3, 4, 5, 6, 7]
Implementation Guidelines
When implementing these in a custom hook, follow these patterns to ensure stability:
• Use for IDs: Store the request ID returned by rAF/rIC in a useRef to track and cancel it during cleanup.
• Cleanup on Unmount: Always return a cleanup function in to call or to prevent memory leaks and "ghost" state updates.
• Throttle State Updates: Be cautious with state updates inside these callbacks. High-refresh-rate displays (120Hz+) can trigger rAF more frequently than needed, potentially causing performance overhead if not throttled.
• Browser Compatibility: While rAF is widely supported, requestIdleCallback is not supported in all browsers (e.g., older Safari versions). Use a polyfill or a fallback for production apps. [3, 8, 9, 10, 11, 12]
let fps = 30;
let lastTime = 0;
function animate(currentTime) {
requestAnimationFrame(animate);
const delta = currentTime - lastTime;
if (delta < 1000 / fps) return; // Skip frame if too early
lastTime = currentTime - (delta % (1000 / fps));
// Perform throttled work
}
requestAnimationFrame(animate);
Summary Comparison
| Feature | |||
|---|---|---|---|
| Primary Goal | Smooth animations/visuals | Background/Low-priority tasks | Non-blocking UI updates |
| Execution Timing | Before next repaint | During browser idle time | React's idle time (interruptible) |
| Best For | Position/Layout updates | Analytics, heavy data processing | Expensive list rendering |
| React Integration | Manual (via ) | Manual (via ) | Native (Concurrent Mode) |
[1] https://layonez.medium.com/performant-animations-with-requestanimationframe-and-react-hooks-99a32c5c9fbf
[2] https://developer.mozilla.org/en-US/docs/Web/API/Window/requestAnimationFrame
[3] https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback
[4] https://en.blog.jasonzk.com/js/requestidlecallback-and-requestanimationframe/
[6] https://www.youtube.com/watch?v=yIpHTYo3PY0
[10] https://dev.to/tawe/requestanimationframe-explained-why-your-ui-feels-laggy-and-how-to-fix-it-3ep2
[11] https://github.com/Chalarangelo/30-seconds-of-code/blob/master/content/snippets/react/s/use-request-animation-frame.md
[12] https://css-tricks.com/using-requestanimationframe-with-react-hooks/
[13] https://stackoverflow.com/questions/38709923/why-is-requestanimationframe-better-than-setinterval-or-settimeout
[14] https://medium.com/@ignatovich.dm/understanding-usedeferredvalue-in-react-enhancing-performance-with-deferred-rendering-ec8eb28aa997
[15] https://medium.com/zestgeek/understanding-reacts-usedeferredvalue-hook-a-comprehensive-guide-with-examples-f8aa3361ee23
[2] https://macarthur.me/posts/navigating-the-event-loop/
[3] https://developer.chrome.com/blog/using-requestidlecallback
[4] https://www.luisball.com/blog/request-animation-frame-versus-request-idle-callback
[5] https://stackoverflow.com/questions/61145102/using-requestanimationframe-inside-requestidlecallback
[6] https://powerfulyang.com/post/104
[7] https://andriii.hashnode.dev/windowrequestidlecallback-all-you-need-to-know
[10] https://www.clicktorelease.com/blog/calculating-fps-with-requestIdleCallback/
[11] https://andriii.hashnode.dev/requestanimationframe-all-you-need-to-know
[12] https://dev.to/sylwia-lask/9-things-youre-overengineering-the-browser-already-solved-them-o99
[13] https://dev.to/codewithrajat/boost-your-web-performance-mastering-javascript-scheduling-methods-56eh
[15] https://caniuse.com/requestidlecallback
[16] https://www.youtube.com/watch?v=oDYT2J5zNHc
[17] https://medium.com/imgcook/a-closer-look-at-react-fiber-b2ab072fcc2a
[18] https://www.youtube.com/watch?v=nect7xrF2go
[19] https://www.debugbear.com/blog/requestanimationframe
[20] https://developer.mozilla.org/en-US/docs/Web/Performance/Guides/CSS_JavaScript_animation_performance
Top comments (0)