The Browser Event Loop

Call stack, task, microtask checkpoint, rendering opportunity. The scheduling model that explains why a synchronous loop freezes the page and a promise chain does not yield a frame.

The Event Loop, Precisely
▶ lab

One call stack, task queues, a microtask checkpoint that drains to empty, and a rendering opportunity between tasks — the model that predicts any ordering puzzle.

Q · Why does this code print A, D, C, B — and what makes that ordering a guarantee rather than an accident of implementation?
Tasks: The Unit That Cannot Be Interrupted
▶ lab

Where tasks come from, why each one runs to completion, and why `setTimeout(fn, 0)` is neither zero nor a promise about when.

Q · What exactly is a task, which browser activities produce one, and what does "runs to completion" cost me?
The Microtask Checkpoint
▶ lab

Drained to empty after every callback, including microtasks queued during the drain — which is exactly why an unbounded promise chain freezes a page with no long task to blame.

Q · When does a promise callback actually run, and how can a page hang without a single long task in the profile?
The Rendering Opportunity
▶ lab

A frame can only be produced between tasks, after the microtask checkpoint — which is the mechanical reason a promise chain never lets the browser paint.

Q · When exactly can the browser produce a frame, and why does my loading state never appear before the work that was supposed to follow it?
Long Tasks
▶ lab

One task that runs long blocks input, rendering and accessibility-tree updates at the same time — which is why "the page froze" is one symptom with one cause.

Q · What is actually happening to the user while one of my tasks is running, and how do I find the task responsible?
What the Main Thread Owns
▶ lab

Script, DOM, style, layout, event dispatch and the accessibility tree share one thread — and knowing what is not on it is what makes moving work possible.

Q · Which work must happen on the thread that owns the DOM, and which work is already somewhere else?
Yielding and Scheduling
▶ lab

Breaking work into pieces the loop can get between — with honest limits: zero is not zero, idle callbacks are not everywhere, and the newer scheduling APIs are not yet universal.

Q · How do I break long work into pieces the browser can interleave with input and rendering, and which primitive should I actually use?