Event Loop Starvation
HardEvent loop starvation occurs when one type of task blocks others from running. Infinite microtasks can starve macrotasks. Long-running synchronous code blocks everything. Understanding these scenarios helps prevent UI freezing and ensures responsive applications.
Interactive Visualization
Call Stack
LIFO - Last In, First Out
Stack empty
Key Points
- Infinite microtasks prevent macrotasks from running
- Long sync operations block the entire thread
- Use setTimeout(fn, 0) to yield control
- Break heavy work into chunks
- Use Web Workers for CPU-intensive tasks
Code Examples
Microtask Starvation
// This blocks forever! function recursivePromise() { Promise.resolve().then(() => { console.log("Microtask"); recursivePromise(); }); } // recursivePromise(); // setTimeout(() => console.log("Never!"), 0); // The microtask queue never drains // setTimeout never gets a chance
Recursively queueing microtasks prevents macrotasks from ever executing.
Yielding with setTimeout
// Bad: Blocks for 5 seconds function heavyTask() { for (let i = 0; i < 1000000000; i++) {} // Blocks! } // Better: Break into chunks function chunkedTask(i = 0) { if (i >= 1000000000) return; // Do chunk of work for (let j = 0; j < 1000; j++, i++) {} // Yield to event loop setTimeout(() => chunkedTask(i), 0); } // Now other code can run between chunks
Use setTimeout to yield control between chunks of work.
Common Mistakes
- Running heavy computation on main thread
- Creating infinite microtask loops
- Not yielding control in long operations
Interview Tips
- Know how to identify starvation scenarios
- Know solutions: setTimeout yielding, Web Workers
- Understand the recursive Promise problem