The engine is only part of the browser
Source 02:43JavaScript can execute a long calculation while a timer counts down, yet the timer's callback does not interrupt that calculation. How can both statements be true? In his 2014 JSConf EU talk, Philip Roberts answers with a simple picture: JavaScript runs on a call stack, while the browser supplies APIs that can manage work outside that stack. A queue and an event loop bring eligible callbacks back to JavaScript later. Watch from 02:43.
Roberts was motivated by realizing that, despite working professionally in JavaScript, he could use callbacks without understanding how they worked. His simplified V8 diagram has a heap, where memory is allocated, and a call stack, which tracks execution. Browser facilities such as the DOM, timers and XMLHttpRequest (XHR, an API for network requests) belong to the surrounding environment. Node has a different host environment, which he compares to a set of native APIs.
This is a 2014 teaching model, not a complete or universal specification of today's browsers. Its single queue, thread descriptions and rendering priority simplify a more complicated system; it omits other scheduling mechanisms and workers. The diagrams are useful for following the examples, not for predicting every ordering or paint.
The call stack records nested synchronous calls
Source 04:32A stack frame represents an active call. Enter a function and a frame goes on top; return and it comes off. In Roberts's example, the file starts as main, then printSquare(4) calls square, which calls multiply(4, 4). Multiplication returns to square, then to printSquare, which logs the result and finishes. The last call in is the first to return. Watch from 04:32.
A stack trace exposes this nesting when an error occurs: Roberts shows baz calling bar, which calls foo, where an error is thrown. Recursion without a stopping point keeps adding frames until the stack limit is reached. His Chrome demonstration stops around 16,000 calls; that is an observation for that run, not a portable limit.
Long synchronous work makes a page appear frozen
Source 07:21Blocking means that work occupying the execution thread prevents other work on that thread from progressing. Roberts illustrates slow work with a huge loop, image processing and a hypothetical sequence of three synchronous network requests. Each request must finish before the next begins; one might never finish. His Chrome demonstration simulates the wait with a long synchronous while loop rather than actually depending on slow network responses. Watch from 07:21.
While it runs, even the Run button does not visibly update after the click. Input and display updates appear to catch up after the loop finishes. The practical problem is the occupied page thread: a responsive interface needs opportunities to process work and update the display.
A browser API can wait while the stack continues
Source 10:26A callback is a function supplied to be called later or by another function. In the timer example, the program logs Hi, calls setTimeout with a callback and a five-second delay, then logs JSConfEU. The timer is managed by the browser; the setTimeout call itself can return, so the rest of the current code proceeds. Watch from 12:51.
In the talk's model, once the timer expires, its callback enters a callback queue: a waiting line for work to run. The event loop checks the queue and stack; when the stack is clear, it takes the first waiting callback and puts it on the stack. The callback then logs there. The timer does not insert JavaScript halfway through the currently running function.
Zero delay defers a callback; it does not guarantee a deadline
Source 15:03Replacing five seconds with setTimeout(..., 0) still produces Hi, then JSConfEU, then there: the current script finishes before the queued callback runs. Zero is a request to run later, not permission to interrupt the current stack. Roberts's drawing treats the timer as immediately ready; that is an explanatory shortcut, not a promise of immediate scheduling. Watch from 15:03.
The XHR example follows the same teaching sequence: initiate a request and supply a callback, continue with other code, and handle the result later if it arrives. The request may never complete; the current stack need not wait for it.
The live visualizer shows callbacks waiting their turn
Source 17:23Roberts built Loop to visualize execution after his animated slides became difficult to maintain. Its demo wraps a DOM event listener and setTimeout; XHR had not yet been shimmed. A click queues a handler, and many clicks can leave handlers waiting before they are processed. This is an instructional visualization rather than a literal view of every browser internal. Watch from 18:12.
In another demo, four timers each request a one-second delay. The fourth callback is still waiting after its timer has elapsed because earlier work is being processed. The requested delay is a minimum before eligibility, not a guaranteed execution time.
A callback is not necessarily asynchronous
Source 20:25The word callback describes a function called by another function; it does not by itself say when. Array forEach calls its callback synchronously on the current stack. Roberts contrasts it with a homemade version that schedules a zero-delay timer for each array item. He notes that his demonstration should also pass the item value. Watch from 20:25.
The synchronous loop occupies the stack until all iterations finish. The alternative first queues callbacks, clears the stack, and runs them later. With a fast console.log, the benefit is hard to see; for slow per-item processing, dividing work can create opportunities for other browser work between pieces. Scheduling itself also takes time, and an individually long callback can still block.
Yielding between pieces can give rendering a chance
Source 22:05To make the difference visible, Roberts adds a simulated render queue and compares slow synchronous and timer-scheduled processing. His 2014 illustration uses 60 frames per second, or about 16.6 milliseconds per frame, as a target. In the simulation a pending render waits for the stack to clear and is given priority over callbacks. That is his pedagogical approximation, not a universal refresh rate or an exact browser rendering algorithm. Watch from 22:05.
The slow synchronous loop blocks the simulated render, just as the earlier busy loop made the page appear frozen. Scheduling many timers also occupies the stack while they are registered, but in the demo that phase is relatively quick; between individual callbacks the renderer gets opportunities to update. Those opportunities are not guarantees of a paint after every item. The lesson behind “don't block the event loop” is to avoid monopolizing the execution thread with slow work when the interface needs to respond.
Frequent events can overwhelm the work queue
Source 24:42A scroll handler that does expensive work can be invoked repeatedly as the user scrolls. Even if individual calls eventually finish, incoming work can accumulate faster than it is handled. Roberts guesses that scroll events occur every frame; he presents that as a guess, not a measured rule. Watch from 24:42.
His suggested remedy is to reduce how often the expensive work runs: wait until scrolling has stopped for a period (debouncing), or limit work to intervals. These are distinct timing choices, both aimed at avoiding unnecessary repeated work.
The visualizer itself deliberately slows execution: Roberts says it parses the code with Esprima, inserts half-second busy loops before and after statements, sends the instrumented code to a web worker, and visualizes what happens. Its dramatic pacing is therefore part of the demonstration, not a measurement of ordinary application speed.