Working on Idle Time

requestIdleCallback(callback, { timeout }) runs low-priority work, such as analytics, when the main thread is idle, so input and animation stay smooth. The callback receives an IdleDeadline: timeRemaining() gives the milliseconds left in the idle period (at most 50), and didTimeout is true when timeout forced the call.

Draining a work queue in idle periodsJavaScript
let left = 200;
let periods = 0;
function work(deadline) {
  periods++;
  while (left > 0 && (deadline.timeRemaining() > 0 || deadline.didTimeout)) {
    left--;
    for (const end = performance.now() + 2; performance.now() < end;);  // 2 ms of fake work
  }
  if (left > 0) requestIdleCallback(work, { timeout: 1000 });
  else console.log(`200 tasks done in ${periods} idle periods`);
}
requestIdleCallback(work, { timeout: 1000 });
Output
200 tasks done in 10 idle periods

requestIdleCallback() is not Baseline because Safari 10 lacks it, so feature-detect and fall back to setTimeout(). To split urgent long tasks, use scheduler.yield() (Chrome 129 1 , Firefox 142 555 , not Safari).