requestIdleCallback works in Chrome 47+, Edge 79+, Firefox 55+, Opera 34+, and Samsung 5+. Safari needs a polyfill. Learn browser support and use cases.

Prince Dewani
May 6, 2026
requestIdleCallback is a W3C JavaScript API that schedules a callback during the browser's idle time, off the main thread. It works in Chrome 47+, Edge 79+, Firefox 55+, Opera 34+, and Samsung Internet 5+, while Safari keeps it behind a feature flag on macOS and iOS and Internet Explorer has no support.
This guide covers what requestIdleCallback is, the browsers that support it, how it compares to setTimeout, the use cases, a polyfill pattern, and known issues.
requestIdleCallback is a W3C method on the Window object that queues a function to run when the browser has spare time at the end of a frame. The callback receives an IdleDeadline object whose timeRemaining method tells you how many milliseconds you can safely use before yielding back to rendering and input.
requestIdleCallback runs by default in every Chromium-based browser, in Firefox, and in Samsung Internet, while Safari on macOS and iOS hide it behind a feature flag and Internet Explorer never added support.
Chrome supports requestIdleCallback by default from Chrome 47 on Windows, macOS, Linux, ChromeOS, and Android. Chrome 1 to 46 did not support it. The same Chromium engine ships in Chrome for Android, so desktop and mobile builds gained the API together.
Microsoft Edge supports requestIdleCallback from Edge 79, the first Chromium-based release, on Windows, macOS, and Linux. Legacy Edge 12 to 18 on the EdgeHTML engine never added the Background Tasks API. Anyone still on legacy Edge needs the setTimeout polyfill from the section below.
Firefox supports requestIdleCallback by default from Firefox 55 on Windows, macOS, Linux, and Android. Firefox 53 and 54 had it disabled by default behind the dom.requestIdleCallback.enabled preference. Firefox 1 to 52 did not support requestIdleCallback at all.
Safari does not support requestIdleCallback by default in any stable version. WebKit ships the implementation behind a feature flag, so Safari on macOS exposes it under Develop, Feature Flags, and Safari on iOS exposes it under Settings, Safari, Advanced, Feature Flags. Most production users will not flip these flags, so a setTimeout polyfill is required to cover Safari desktop and iPhone visitors.
Opera supports requestIdleCallback from Opera 34 on Windows, macOS, Linux, and Android. Opera 9 to 33 did not support it. Opera Mobile follows the same Chromium baseline as Opera desktop, so the API is available on the modern mobile builds.
Samsung Internet supports requestIdleCallback from version 5.0 on Galaxy phones and tablets. The browser is built on Chromium, so it follows the same scheduling rules as Chrome for Android. Samsung Internet 4 and earlier did not support the API.
Chrome for Android supports requestIdleCallback from Chrome 47, the same milestone as desktop Chrome. Firefox for Android picked it up in Firefox 55. The legacy stock Android Browser, last shipped with Android 4.4 KitKat, never added the API and is fully retired on shipping devices.
Internet Explorer does not support requestIdleCallback in any version. Microsoft never added the Background Tasks API to IE 9, 10, or 11, and the browser is now end of life. Anyone still on IE needs the setTimeout polyfill, since the API does not exist on the Window object.
Note: requestIdleCallback breaks in Safari and on iOS without a polyfill. Test it on real browsers and OS with TestMu AI. Try TestMu AI free!
Both APIs schedule a function to run later, but only requestIdleCallback waits for the browser to be idle. setTimeout fires after a fixed delay no matter what the main thread is doing, so heavy work inside a setTimeout callback can still block input and rendering.
| Dimension | requestIdleCallback | setTimeout |
|---|---|---|
| Trigger | Fires when the browser is idle at frame end | Fires after the supplied delay in milliseconds |
| Time guarantee | Best effort, up to 50 ms slice per call | Yes, the callback runs after the delay elapses |
| Callback parameter | IdleDeadline with timeRemaining and didTimeout | None, the callback receives only the arguments you passed |
| Effect on input and animation | Yields to user input, scroll, and animation frames | Can block input and animation when the work is heavy |
| Browser reach | Chrome 47+, Edge 79+, Firefox 55+, Opera 34+, Samsung 5+; Safari behind a flag | Universal, every browser since the IE 4 era |
| Best fit | Background work, analytics, prefetch, log batching | Timed delays, debouncing, animations, single-frame deferrals |
requestIdleCallback fits any task you can defer until the user pauses scrolling or typing. Production teams use it to keep the main thread free during page load and user interactions.
The standard polyfill wraps setTimeout in a function that mirrors the requestIdleCallback signature and returns a fake IdleDeadline. Add the shim once at app startup so every later call works on Safari, iOS, and any browser that lacks the native method.
// Polyfill requestIdleCallback for Safari and any browser without native support.
// Paste into your app bootstrap or a <script> tag in the document <head>.
window.requestIdleCallback =
window.requestIdleCallback ||
function (callback, options) {
const start = Date.now();
const timeout = (options && options.timeout) || 0;
return setTimeout(function () {
callback({
didTimeout: false,
timeRemaining: function () {
return Math.max(0, 50 - (Date.now() - start));
}
});
}, 1);
};
window.cancelIdleCallback =
window.cancelIdleCallback ||
function (id) {
clearTimeout(id);
};
// Verify the shim is in place.
console.log("requestIdleCallback in window:", "requestIdleCallback" in window);If the console prints false, the script ran in a worker scope or before window existed; move the snippet into the document head and reload.
requestIdleCallback ships in most engines, but a few real edge cases still bite production teams. The biggest hits are Safari support, the 50 ms slice cap, iframe budget sharing, and the React 18 scheduler change.
In my experience, the most surprising failure happens on iPhone Safari. A team ships a clever idle-time prefetch on Chrome, ignores the Safari gap, and learns six months later that a third of their iOS users have been hitting a cold cache on every navigation. Always pair the API with a feature check and the setTimeout shim above, and verify the path on a real iPhone before you ship.
All requestIdleCallback version numbers and platform notes in this guide come from these primary sources:
Did you find this page helpful?
More Related Hubs
TestMu AI forEnterprise
Get access to solutions built on Enterprise
grade security, privacy, & compliance