Frontend Labs
⋯

15. Timers and scheduling: setTimeout, rAF, requestIdleCallback, MessageChannel

Not all "run this later" APIs are equal — each is a different macrotask source tuned for a different purpose:

API Fires Use for
setTimeout(fn, 0) Next macrotask turn, but browsers clamp nested timeouts to a minimum ~4ms after 5 levels of nesting General deferred work
requestAnimationFrame(fn) Right before the next repaint, synced to the display's refresh rate (~60Hz = 16.6ms) Any visual animation — never animate with setInterval
requestIdleCallback(fn) During browser idle periods, with a deadline you must respect Low-priority background work (analytics batching, prefetch) that shouldn't compete with rendering
queueMicrotask(fn) End of the current task, before the next macrotask/paint (§12) Deferring work to just after the current synchronous block, without a full event-loop turn
MessageChannel Macrotask, but with no minimum delay clamp unlike setTimeout(fn, 0) The fastest legal way to yield to the event loop — used internally by React's scheduler
function animate() {
  element.style.transform = `translateX(${x++}px)`;
  if (x < 300) requestAnimationFrame(animate);   // self-scheduling, paced to the display
}
requestAnimationFrame(animate);

Generated from real-life-JS-guide.md · 8 Oct 2026 16:36