Learn how the JavaScript Event Loop works internally, why Promises execute before setTimeout(), how browsers schedule rendering, and how modern engines like V8 coordinate synchronous and asynchronous execution.
Why This Matters
One of the most common frontend interview questions is:
> Why does Promise.then() execute before setTimeout(..., 0)?
Understanding the answer requires more than memorizing "microtasks run first." You need to understand how the browser runtime, JavaScript engine, Event Loop, Web APIs, Call Stack, and rendering pipeline work together.
This knowledge helps you:
- Write performant applications.
- Debug asynchronous bugs.
- Optimize Core Web Vitals.
- Avoid UI freezes.
- Perform well in frontend interviews.
Learning Objectives
- Explain the Event Loop from first principles.
- Differentiate synchronous and asynchronous execution.
- Understand the Call Stack, Web APIs, Microtask Queue and Macrotask Queue.
- Predict execution order confidently.
- Recognize performance pitfalls.
Prerequisites
- JavaScript fundamentals
- Functions
- Promises
- async/await
- Browser basics
Visual Mental Model
JavaScript
│
▼
Call Stack
│
▼
Web APIs
│
├────────────┐
▼ ▼
Microtasks Macrotasks
│ │
└────┬───────┘
▼
Event Loop
│
▼
Browser Render
Core Architecture
Call Stack
The Call Stack is a Last-In-First-Out (LIFO) structure that stores execution contexts.
Web APIs
The browser provides asynchronous capabilities including timers, DOM events and fetch.
Microtask Queue
Contains Promise callbacks, async/await continuations, queueMicrotask and MutationObserver callbacks.
Macrotask Queue
Contains callbacks such as setTimeout and setInterval.
Event Loop Lifecycle
JavaScript Event Loop
Start
│
▼
Execute Synchronous JavaScript
│
▼
Is the Call Stack Empty?
│
┌──────────┴──────────┐
│ │
No Yes
│ │
Continue executing Flush Microtask Queue
synchronous code │
▼
Any Microtasks Remaining?
┌─────────┴─────────┐
│ │
Yes No
│ │
Execute Next Microtask Browser Rendering
│ │
└─────────┬─────────┘
▼
Execute One Macrotask
│
▼
Repeat Next Event Loop Cycle
Code Walkthrough
console.log("1. Main Script Start");
setTimeout(() => {
console.log("2. Macrotask (Timeout)");
}, 0);
Promise.resolve()
.then(() => console.log("3. Microtask 1"))
.then(() => console.log("4. Microtask 2"));
console.log("5. Main Script End");
Output
1. Main Script Start
5. Main Script End
3. Microtask 1
4. Microtask 2
2. Macrotask (Timeout)
Under the Hood
The JavaScript engine executes JavaScript only. The browser runtime coordinates timers, DOM, networking, rendering and the Event Loop.
Production Example
Large applications like e-commerce sites use the Event Loop to coordinate rendering, network requests and user interactions while keeping the UI responsive.
Performance Considerations
- Avoid long synchronous tasks.
- Use Web Workers for CPU-intensive work.
- Break large computations into smaller chunks.
- Profile long tasks with Chrome DevTools.
Common Mistakes
- Assuming setTimeout(0) runs immediately.
- Ignoring microtask priority.
- Blocking the main thread.
- Forgetting cleanup of async work.
- Creating endless Promise chains.
Best Practices
- Keep synchronous work small.
- Prefer asynchronous APIs.
- Measure performance instead of guessing.
- Understand microtask vs macrotask behavior.
Interview Questions
Why does Promise execute before setTimeout?
Because Promise callbacks are microtasks and the Event Loop drains the microtask queue before executing the next macrotask.
Can microtasks starve rendering?
Yes. Continuously adding microtasks can delay rendering.
---
Coding Challenge
Predict the output:
console.log("A");
setTimeout(() => console.log("B"));
Promise.resolve().then(() => console.log("C"));
console.log("D");
---
FAQ
Is the Event Loop part of JavaScript?
No. It belongs to the runtime environment.
Why doesn't setTimeout(0) execute immediately?
Because the current task and all pending microtasks must finish first.
Related Concepts
- Promises
- async/await
- Web Workers
- requestAnimationFrame
- requestIdleCallback
Summary
The Event Loop coordinates synchronous JavaScript, browser APIs, microtasks, macrotasks and rendering. Understanding it is essential for writing performant web applications and succeeding in frontend interviews.
Key Takeaways
- JavaScript executes on a single Call Stack.
- Microtasks run before macrotasks.
- Rendering happens between Event Loop iterations.
- Long synchronous tasks block rendering and hurt Core Web Vitals.
