| |

Internet Beginner 09 ๐ŸŒ Browsers and How They Work

โฑ๏ธ Estimated read: 12 min | |

A web browser is not a single program. It is a collection of processes and threads working together, each responsible for a different part of the job: one process handles the address bar and tabs, another fetches data from the network, and another turns HTML, CSS, and JavaScript into the page you see and interact with. This multi-process architecture is what allows a browser to keep one tab responsive when another is busy, and to isolate a crashed page from the rest of the browser.

The journey from typing a URL to seeing a rendered page has two major phases. The first is navigation: the browser resolves the domain, establishes a connection, sends an HTTP request, and receives the response. The second is rendering: the renderer process parses the HTML into a DOM tree, applies styles, calculates layout, and paints pixels to the screen . Each phase involves multiple subsystems, and understanding them explains why some pages load instantly while others feel sluggish.

Key point: A browser is a multi-process system where the browser process handles navigation and UI, the network thread fetches resources, and the renderer process (with its main thread and compositor thread) turns HTML, CSS, and JavaScript into pixels on the screen.


Why browsers are built as multi-process systems

The stability problem. In a single-process browser, a crash in one tab would take down the entire application. A memory leak in one page could exhaust resources for all pages. The multi-process architecture isolates each tab (or group of tabs from the same site) into its own renderer process. If one renderer crashes, the browser process survives, and the other tabs continue working .

The security problem. Web pages run untrusted code. JavaScript from one site must not be able to read data from another site, access the filesystem, or interfere with the browser’s own memory. Process isolation provides a hardware-enforced boundary: the renderer process runs in a sandbox with limited privileges, and the browser process mediates access to sensitive resources like the network and the filesystem .

The responsiveness problem. A page that runs a long JavaScript loop can freeze its own tab, but it should not freeze the entire browser. The browser process and the renderer process are separate, so the address bar, tab switching, and other browser UI remain responsive even when a page’s main thread is blocked .

The performance problem. Rendering is expensive. Parsing HTML, calculating styles, performing layout, and painting pixels all consume CPU time. Separating the main thread (which runs JavaScript and layout) from the compositor thread (which handles scrolling and animations) means that scrolling can continue smoothly even while JavaScript is executing . This separation is a deliberate performance optimization: animations and scrolling are handled on a thread that is not blocked by application code.


a. Navigation: from URL to response

Navigation begins in the browser process. The UI thread handles the address bar input, deciding whether the text is a search query or a URL. If it is a URL, the UI thread initiates a network call, and the network thread performs the DNS lookup and establishes a connection .

The network thread sends an HTTP request and receives the response. It checks the Content-Type header to determine what kind of data it received. If the response is HTML, the network thread passes it to the renderer process. If it is a file like a ZIP archive, the browser treats it as a download and passes it to the download manager instead . The network thread also runs safety checks: it consults the Safe Browsing list to warn about malicious sites, and it applies Cross-Origin Read Blocking (CORB) to prevent sensitive cross-site data from reaching the renderer .

Once the response is confirmed as HTML and the safety checks pass, the browser process finds or starts a renderer process for the tab. It then commits the navigation by sending an IPC message to the renderer, along with the data stream. From this point, the renderer process owns the page .


b. Rendering: from HTML to pixels

The renderer process is where the page is built. Its main thread performs a pipeline of tasks: parsing, style calculation, layout, paint, and compositing .

Parsing. The main thread parses the HTML text into a Document Object Model (DOM) tree. The DOM is the browser’s internal representation of the page, and it is what JavaScript interacts with. The HTML parser is forgiving: missing closing tags and other errors are handled according to the HTML specification, not rejected . While the main thread parses, a preload scanner runs concurrently, looking ahead in the HTML for resources like images and stylesheets, and requesting them early to speed up loading .

JavaScript blocks parsing. When the parser encounters a <script> tag, it pauses. JavaScript can modify the document structure using document.write(), so the parser must wait for the script to load and execute before continuing . This is why script placement matters: a script at the top of the document can delay the rendering of everything below it. Developers can use async or defer attributes to tell the browser to load and execute scripts without blocking the parser.

Style calculation. The main thread parses CSS and determines the computed style for each DOM node. Even without author-provided CSS, every element has a default style from the browser’s built-in stylesheet .

Layout. The main thread walks the DOM and computed styles to calculate the geometry of every visible element: its position and size. The result is a layout tree, which contains only the elements that are actually displayed. Elements with display: none are excluded; elements with visibility: hidden are included because they still occupy space .

Paint. The main thread creates a paint record: an ordered list of drawing instructions. This step determines the order in which elements are painted, which matters for overlapping elements and z-index .

Compositing. The painted layers are assembled by the compositor thread into the final screen image. The compositor thread runs separately from the main thread, which is why scrolling and some animations can remain smooth even when JavaScript is busy .


c. The main thread and the compositor thread

The renderer process has two critical threads. The main thread runs JavaScript, parses HTML and CSS, calculates layout, and handles user input events. It is single-threaded for JavaScript, which means a long-running script blocks everything else on that thread, including input handling and rendering updates .

The compositor thread handles scrolling, animations, and compositing. It runs independently of the main thread, so scrolling can continue even if JavaScript is executing. This separation is why modern browsers feel smooth even on JavaScript-heavy pages: the compositor can move already-painted layers without waiting for the main thread to finish its work .

When the main thread is busy, the page may not respond to clicks or keystrokes. This is why performance advice consistently emphasizes keeping JavaScript tasks short and yielding to the browser between tasks. The main thread is the page’s UI thread, and blocking it blocks the user experience .


Complete Example Session

The following session traces the full journey from typing a URL to seeing a rendered page, highlighting the process and thread responsible at each step.

// ============================================
// PART 1: INPUT AND DECISION
// ============================================
// User types "example.com" in the address bar
// Browser process UI thread handles input
// Decides: is this a search query or a URL?
// It is a URL โ€” proceed with navigation

// ============================================
// PART 2: NETWORK REQUEST
// ============================================
// UI thread sends the URL to the network thread
// Network thread performs DNS lookup
// Network thread establishes TCP connection
// Network thread performs TLS handshake (HTTPS)
// Network thread sends HTTP GET request

// ============================================
// PART 3: RESPONSE RECEIVED
// ============================================
// Network thread receives HTTP response
// Checks Content-Type: text/html
// Runs Safe Browsing check
// Runs CORB check
// Determines this is HTML, not a download

// ============================================
// PART 4: RENDERER SELECTION
// ============================================
// UI thread finds or creates a renderer process
// UI thread commits navigation via IPC
// Sends HTML data stream to renderer process
// Renderer process now owns the page

// ============================================
// PART 5: PARSING (RENDERER MAIN THREAD)
// ============================================
// Main thread parses HTML into DOM tree
// Preload scanner finds <link> and <img> tags
// Preload scanner requests resources in parallel
// Parser encounters <script> tag
// Parser pauses, loads and executes JavaScript
// Parser resumes after script completes

// ============================================
// PART 6: STYLE CALCULATION
// ============================================
// Main thread parses CSS
// Computes style for each DOM node
// Applies default styles + author styles

// ============================================
// PART 7: LAYOUT
// ============================================
// Main thread walks DOM and computed styles
// Calculates position and size of each element
// Builds layout tree (visible elements only)

// ============================================
// PART 8: PAINT
// ============================================
// Main thread creates paint records
// Determines drawing order (z-index, overlaps)
// Converts layout tree into drawing commands

// ============================================
// PART 9: COMPOSITING
// ============================================
// Compositor thread assembles layers
// Combines painted layers into final image
// Sends frame to GPU for display
// Page appears on screen

// ============================================
// PART 10: INTERACTION
// ============================================
// User scrolls: compositor thread handles it
// User clicks: main thread handles event
// If main thread is busy, click waits
// If compositor is scrolling, it stays smooth

The ten parts trace the full journey: input, network, response, renderer selection, parsing, style, layout, paint, compositing, and interaction. What the session demonstrates is that the browser is not a single actor but a coordinated system of processes and threads, each responsible for a specific stage of the pipeline.


Quick Reference

Browser Processes and Threads

ComponentResponsibility
Browser processUI, tabs, address bar, navigation coordination
UI threadHandles input, decides search vs URL
Network threadDNS, TCP, TLS, HTTP request/response
Renderer processParses and renders the page
Main thread (renderer)HTML parsing, CSS, layout, paint, JavaScript
Compositor threadScrolling, animations, layer assembly

Rendering Pipeline

StageThreadOutput
Parse HTMLMainDOM tree
Parse CSSMainComputed styles
LayoutMainLayout tree (geometry)
PaintMainPaint records (drawing order)
CompositeCompositorFinal screen image

Resource Loading

MechanismBehavior
Preload scannerFinds resources ahead of parser
<script>Blocks parsing unless async/defer
asyncLoads and runs without blocking parser
deferRuns after parsing completes

Key Performance Concepts

ConceptMeaning
Main thread blockingLong JS blocks input and rendering
Compositor threadHandles scroll/animation independently
Frame budget~16ms per frame for 60fps
ReflowRecalculating layout after DOM change

Best Practices

โœ… Do This:

// Use async or defer on script tags
// Place scripts at the end of the body
// Keep JavaScript tasks short
// Use requestAnimationFrame for animations
// Preload critical resources with <link rel="preload">

โŒ Don’t Do This:

// Use document.write() after page load
// Run long synchronous loops on the main thread
// Block parsing with synchronous scripts
// Ignore the main thread when animating
// Assume the browser renders instantly

Common Pitfalls

PitfallWhy It HappensFix
Page freezes during scriptLong JS blocks main threadBreak work into smaller tasks
Scripts block rendering<script> without async/deferAdd async or defer
Slow first paintLarge CSS or blocking scriptsInline critical CSS, defer scripts
Janky scrollingMain thread busyUse compositor-friendly animations
Layout thrashingReading and writing DOM alternatelyBatch reads, then batch writes

Real-World Examples

1. Preload scanner finds image

<img src="hero.jpg"> <!-- Preload scanner requests immediately -->

2. Blocking script

<script src="app.js"></script> <!-- Parser pauses -->

3. Non-blocking script

<script src="app.js" defer></script> <!-- Runs after parsing -->

4. Async script

<script src="analytics.js" async></script> <!-- Runs when ready -->

5. Compositor-friendly animation

transform: translateX(100px); /* Compositor handles it */

6. Layout-triggering animation

left: 100px; /* Forces layout on main thread */

7. Critical CSS inlined

<style>/* critical styles */</style>

8. Preload font

<link rel="preload" href="font.woff2" as="font">

9. requestAnimationFrame

requestAnimationFrame(() => { /* update animation */ });

10. Web Worker for heavy work

const worker = new Worker('worker.js');

Visual

Browser Process Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  BROWSER PROCESS                             โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚ UI Thread: address bar, tabs, input    โ”‚  โ”‚
โ”‚  โ”‚ Network Thread: DNS, TCP, HTTP         โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚                   โ”‚ IPC                      โ”‚
โ”‚                   โ–ผ                          โ”‚
โ”‚  RENDERER PROCESS                            โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚ Main Thread: parse, style, layout, JS  โ”‚  โ”‚
โ”‚  โ”‚ Compositor Thread: scroll, composite   โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Rendering Pipeline

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  HTML โ†’ DOM                                  โ”‚
โ”‚         โ”‚                                    โ”‚
โ”‚         โ–ผ                                    โ”‚
โ”‚  CSS โ†’ Computed Styles                       โ”‚
โ”‚         โ”‚                                    โ”‚
โ”‚         โ–ผ                                    โ”‚
โ”‚  Layout (geometry)                           โ”‚
โ”‚         โ”‚                                    โ”‚
โ”‚         โ–ผ                                    โ”‚
โ”‚  Paint (drawing order)                       โ”‚
โ”‚         โ”‚                                    โ”‚
โ”‚         โ–ผ                                    โ”‚
โ”‚  Composite (layers โ†’ screen)                 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Main Thread vs Compositor Thread

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  MAIN THREAD                                 โ”‚
โ”‚  JavaScript, parsing, style, layout, paint   โ”‚
โ”‚  Blocked by long tasks                       โ”‚
โ”‚                                              โ”‚
โ”‚  COMPOSITOR THREAD                           โ”‚
โ”‚  Scrolling, animations, layer assembly       โ”‚
โ”‚  Independent of main thread                  โ”‚
โ”‚  Keeps scrolling smooth during JS execution  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Script Loading Behavior

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  <script>          โ†’ parser blocks            โ”‚
โ”‚  <script async>    โ†’ loads in parallel,      โ”‚
โ”‚                       runs when ready        โ”‚
โ”‚  <script defer>    โ†’ loads in parallel,      โ”‚
โ”‚                       runs after parsing     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Summary

ItemValue
Browser architectureMulti-process (browser, renderer, GPU)
NavigationUI thread โ†’ network thread โ†’ renderer
DOMInternal representation of HTML
Main threadParses, styles, lays out, paints, runs JS
Compositor threadScrolling, animations, layer assembly
Preload scannerFinds resources ahead of parser
Blocking scriptPauses HTML parsing
Rendering pipelineParse โ†’ Style โ†’ Layout โ†’ Paint โ†’ Composite

Key takeaways:

  • Browsers are multi-process systems. The browser process handles UI and navigation, the renderer process handles rendering, and the compositor thread handles scrolling and animations independently of JavaScript .
  • Navigation is a coordinated process. The UI thread initiates, the network thread fetches, and the renderer process receives the data stream .
  • The rendering pipeline has five stages. Parsing builds the DOM, style calculation determines appearance, layout calculates geometry, paint records drawing order, and compositing assembles the final image .
  • JavaScript blocks the main thread. A long script prevents input handling and rendering updates, which is why performance advice emphasizes short tasks and yielding .
  • The preload scanner improves loading speed. It finds resources in the HTML ahead of the parser and requests them in parallel .
  • Script placement matters. A <script> tag without async or defer pauses HTML parsing until the script loads and executes .
  • The compositor thread keeps scrolling smooth. Because it runs separately from the main thread, scrolling and some animations continue even when JavaScript is busy .

Remember: A browser is not a single program that “displays web pages.” It is a coordinated system of processes and threads, each responsible for a specific part of the journey from URL to pixels. The browser process handles navigation, the network thread fetches data, and the renderer process builds the page through a pipeline of parsing, styling, layout, painting, and compositing. The main thread is where JavaScript runs and where rendering work happens, which is why long scripts cause the page to freeze. The compositor thread is why scrolling stays smooth even when the main thread is busy. Understanding this architecture explains why pages load the way they do, and why some performance problems are solved by changing code while others are solved by changing how resources are loaded.


Was this helpful?


Stop using slow, ad-bloated tool sites! ๐Ÿคฎ

๐Ÿ”Ž Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
โœ… Finance (Mortgage, Interest, Inflation)
โœ… Tech (Base64, JSON, Dev Suite, IP)
โœ… Health (BMI, BMR, TDEE)
โœ… Productivity (Timer, Workspace, QR)

โšก๏ธ Fast & Private
๐Ÿ”’ No data leaves your device
๐Ÿ’Ž 100% Free

๐Ÿ”— Use it now: https://tools.kandz.me
๐Ÿ”– Bookmark itโ€”youโ€™ll need it later!