Microtask Starvation: The Silent App Killer

#JavaScript #EventLoop Most developers think they understand the JavaScript event loop. Very few understand how it can quietly break their app. Let’s talk about Microtask Starvation 👇 In JavaScript, the event loop roughly follows this cycle: 1. Execute a macrotask (script, timer, I/O) 2. Drain ALL microtasks 3. The browser may render 4. Repeat The critical rule? 👉 𝑴𝒊𝒄𝒓𝒐𝒕𝒂𝒔𝒌𝒔 𝒂𝒓𝒆 𝒂𝒍𝒘𝒂𝒚𝒔 𝒇𝒖𝒍𝒍𝒚 𝒅𝒓𝒂𝒊𝒏𝒆𝒅 𝒃𝒆𝒇𝒐𝒓𝒆 𝒕𝒉𝒆 𝒆𝒗𝒆𝒏𝒕 𝒍𝒐𝒐𝒑 𝒎𝒐𝒗𝒆𝒔 𝒐𝒏. Now here’s where things go wrong. What is Microtask Starvation? Microtask starvation happens when microtasks keep scheduling more microtasks… …and the queue never becomes empty. function loop() { Promise.resolve().then(loop); } loop(); This creates an infinite stream of microtasks. Since the event loop must finish all microtasks before continuing: ❌ setTimeout callbacks are delayed indefinitely ❌ UI updates don’t happen ❌ User interactions feel ignored ❌ Your app appears frozen Because the event loop never proceeds to the next macrotask. 𝗪𝗵𝘆 𝘁𝗵𝗶𝘀 𝗺𝗮𝘁𝘁𝗲𝗿𝘀? Microtasks (Promises, async/await) feel lightweight, so they’re easy to overuse. But they run before the event loop continues to the next task, which means they can block: 1. Rendering 2. User interactions 3. Timers And no, the browser won’t step in and save you. It will keep executing your microtasks exactly as instructed. 𝗛𝗼𝘄 𝘁𝗼 𝗮𝘃𝗼𝗶𝗱 𝗶𝘁? You need to yield control back to the event loop. await new Promise(r => setTimeout(r, 0)); or setTimeout(fn, 0); This schedules a macrotask and allows the browser to continue processing rendering and events. 𝗧𝗵𝗲 𝘁𝗮𝗸𝗲𝗮𝘄𝗮𝘆 If your UI freezes while “nothing heavy is happening,” there’s a good chance you’ve accidentally created a microtask loop.

  • graphical user interface, diagram

To view or add a comment, sign in

Explore content categories