Master JavaScript’s Single Thread: From Browser Processes to the Event Loop
This article systematically explains how browsers use multiple processes and threads, how the rendering pipeline works, why JavaScript runs on a single thread, and how the event loop, macrotasks, microtasks, timers, and Web Workers interact to affect performance and stability.
Distinguish Process and Thread
A process is an independent OS resource (a factory) while a thread is a worker inside that process (a worker in the factory). In a browser each process has its own memory space; threads within the same process share that memory.
<code>- Process is a factory with independent resources
- Threads are workers that cooperate inside the factory
- One process can contain one or more threads</code>Browser Is Multi‑Process
Opening a new tab creates a separate renderer process; the main Browser process coordinates UI, networking, and other tabs. Typical processes include the Browser (main) process, Renderer processes (one per tab), GPU process, and plugin processes.
Browser process handles UI, tab management, and resource allocation.
Renderer process parses HTML/CSS, builds the render tree, and paints.
Communication: Browser process receives a request, forwards it via RendererHost to the Renderer, which performs rendering and sends the result back for display.
Thread Relationships in the Browser Engine
GUI Rendering Thread
Responsible for parsing HTML/CSS, building the DOM and render trees, layout, and painting. It is mutually exclusive with the JavaScript engine thread.
JavaScript Engine Thread
Executes JavaScript code (e.g., V8). While it runs, the GUI thread is paused; UI updates are queued until the engine becomes idle.
Event Trigger Thread
Managed by the browser, it receives events (clicks, AJAX responses, timers) and pushes callbacks onto the task queue for the JS engine.
Timer Thread
Handles
setTimeoutand
setIntervaltiming so that the single‑threaded JS engine is not blocked.
Async HTTP Thread
Performs network requests; on state change it posts an event to the task queue.
WebWorker and SharedWorker
WebWorker runs in a separate thread created by the browser (cannot access DOM). SharedWorker runs in its own process and can be shared across multiple renderer processes.
Simple Browser Rendering Flow
Parse HTML → build DOM tree.
Parse CSS → build render tree.
Layout (calculate sizes/positions).
Paint (rasterize pixels).
Composite layers via GPU and display.
After rendering, the
loadevent fires;
DOMContentLoadedfires earlier when only the DOM is ready.
CSS Loading and Layers
CSS loads asynchronously and does not block DOM parsing, but rendering (building the render tree) waits for CSS because style information is required.
Layers: normal layers belong to the default composite layer; hardware‑accelerated elements (e.g., using
translate3d,
opacity) create separate composite layers that are rasterized independently, improving performance when used sparingly.
From Event Loop to JavaScript Execution
JavaScript tasks are divided into synchronous (executed on the main call stack) and asynchronous (queued by the event‑trigger thread). When the call stack is empty, the engine drains the task queue, executing callbacks.
Timers
setTimeoutschedules a callback via the timer thread; the minimum delay is 4 ms per the HTML spec.
<code>setTimeout(function(){ console.log('hello!'); }, 1000);
console.log('begin');</code>Output order:
begin→
hello!.
macrotask vs microtask
Macrotasks include the main script,
setTimeout,
setInterval, etc. After each macrotask, the engine runs all pending microtasks (Promises,
process.nextTick) before rendering.
<code>console.log('script start');
setTimeout(()=> console.log('setTimeout'), 0);
Promise.resolve().then(()=> console.log('promise1')).then(()=> console.log('promise2'));
console.log('script end');</code>Execution order:
script start,
script end,
promise1,
promise2,
setTimeout.
Conclusion
Understanding the full browser pipeline—from process isolation, thread cooperation, rendering steps, to the event loop and task queues—helps developers write performant, non‑blocking JavaScript and avoid common pitfalls such as long‑running scripts, excessive layer creation, or misuse of timers.
Tencent IMWeb Frontend Team
IMWeb Frontend Community gathering frontend development enthusiasts. Follow us for refined live courses by top experts, cutting‑edge technical posts, and to sharpen your frontend skills.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.