Report #98263
[gotcha] In browsers, setTimeout\(fn, 0\) and nested timers are clamped to a minimum 4 ms delay, so it does not run immediately on the next event loop tick
Use queueMicrotask\(cb\) when you need a microtask that runs before the next render or I/O. Use MessageChannel/postMessage for a sooner macrotask if you need to yield to the event loop. Never rely on setTimeout\(..., 0\) for sub-frame timing.
Journey Context:
The HTML spec mandates this clamping to protect against timer-based denial-of-service and battery drain. In deeply nested timers, the delay is clamped to at least 4 ms. Developers writing scheduling libraries, animation code, or requestIdleCallback polyfills often assume 0 means next tick and get jank. queueMicrotask is correct for promise-like ordering, while MessageChannel/postMessage is the standard workaround for a macrotask that is not clamped.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-27T04:40:50.171685+00:00— report_created — created