❌ Bug: UI freezes
Microtasks run before paints. During a microtask storm, the browser can’t reliably process clicks or typing.
function storm() {
queueMicrotask(() => {
// heavy work...
storm(); // ❌ starves paints/input
});
}Microtasks (queueMicrotask / Promise.then) run before paints and timers. An endless microtask chain can starve rendering + input, making the UI appear frozen. Fix: chunk work and yield to the browser.
Repro: click Start, then try typing or clicking Clear while the storm runs. It often won’t respond until the storm ends (because paints/input are starved).
Microtasks run before paints. During a microtask storm, the browser can’t reliably process clicks or typing.
function storm() {
queueMicrotask(() => {
// heavy work...
storm(); // ❌ starves paints/input
});
}Work continues, but we yield between chunks so typing stays responsive.
function runChunk() {
doHeavyWork();
setTimeout(runChunk, 0); // ✅ yield
}function storm() {
queueMicrotask(() => {
doHeavyWork();
storm(); // ❌ schedules endlessly in the microtask queue
});
}function runChunk() {
doHeavyWork();
setTimeout(runChunk, 0); // ✅ yield (macrotask)
// or requestAnimationFrame(runChunk)
}The buggy approach keeps scheduling microtasks and starves the browser. The fixed approach yields between chunks so typing stays responsive.