35 min read Browser Architecture Lesson 5 (of 12)
Part 2 — Browser Engine, JavaScript & TypeScript

Lesson 05 — How the Browser Builds a Web Page: DOM, CSSOM, Layout, Paint & JavaScript

Explore the complete journey of the Critical Rendering Path (CRP): from raw incoming network bytes to the DOM, CSSOM, Render Tree, Layout, Paint, GPU Rasterization, and Compositing.

What We Will Learn in this Lesson

By the end of this lesson, you will clearly understand:

What a web browser actually does under the hood
How browsers ingest and decode HTML documents
How the DOM is constructed from raw bytes
How CSS is parsed into the CSSOM tree
How the DOM and CSSOM merge into the Render Tree
The difference between the DOM and the Render Tree
How Layout (Reflow) calculates physical geometry
The roles of Paint, Rasterization, and Compositing
Where JavaScript intervenes in the rendering loop
How physical display pixels are produced at 60 FPS

1. What Actually Happens When We Open a Website?

Imagine you type a URL into your browser's address bar:

https://bitbotlab.com

Within a few hundred milliseconds, a complete, interactive, beautifully designed web page appears on your screen.

To an outside observer, it looks deceptively simple:

"The website opened."

Yet inside the browser engine, a breathtaking sequence of high-performance systems engineering operations has just taken place:

1 Fetching resources from the server: Resolving DNS, initiating TCP handshakes, negotiating TLS cryptography, and receiving the HTTP stream.
2 Parsing HTML: Decoding raw stream bytes into tokens, tags, and an in-memory Document Object Model (DOM) tree.
3 Parsing CSS: Evaluating selectors, inheritance, and cascade rules to assemble the CSS Object Model (CSSOM) tree.
4 Computing Layout (Reflow): Calculating the precise pixel coordinates (X, Y) and dimensions (width, height) for every visible box on the screen.
5 Painting visual records: Generating drawing instructions for colors, borders, drop shadows, and font glyphs.
6 Rasterization & Compositing: Translating drawing records into pixel bitmaps and leveraging the GPU to assemble layered frames.

And whenever JavaScript runs, it can mutate the DOM or CSSOM at any moment, initiating localized recalculations throughout this pipeline.

Behind every web page you see lies a complete, multi-threaded internal processing pipeline.

2. What Does the Browser Receive First?

When loading a web page, the browser's networking stack receives diverse resource streams over the socket:

  • HTML (HyperText Markup Language — the foundational structural document)
  • CSS (Cascading Style Sheets — the visual presentation specifications)
  • JavaScript (The algorithmic code driving dynamic behaviors)
  • Images (Raster and vector media: PNG, JPEG, WebP, SVG)
  • Fonts (WOFF2, TTF font glyph binaries)
  • Videos & Media (Audio/video streaming chunks)

Let us begin with HTML. The server sends back raw bytes, which the browser decodes into plain text characters according to the specified encoding (typically UTF-8):

<!DOCTYPE html>
<html>
  <head>
    <title>BitBotLab</title>
  </head>
  <body>
    <h1>Learn Computer Science</h1>
    <p>From computers to AI.</p>
  </body>
</html>

The browser's immediate task is to take this flat string of characters and construct an internal in-memory representation that can be manipulated and displayed.

3. HTML Parsing

A browser cannot draw raw text directly onto a display. It processes the stream through an HTML Parser, which reads the sequence of characters and markup tags.

The parser analyzes:

  • Which element has opened (e.g., <body>)
  • Which element has closed (e.g., </body>)
  • Which elements are nested inside other elements (parent-child relationships)
  • What attributes are specified (e.g., class="hero" or id="menu")
  • The overall hierarchical depth of the document

As tokens are emitted from the tokenizer, the tree construction algorithm builds an in-memory tree structure.

4. How the DOM is Constructed

This resulting tree data structure is known universally as:

DOM — Document Object Model

Consider this minimal snippet:

<main>
  <h1>Learn Computer Science</h1>
  <p>From computers to AI.</p>
</main>

The browser represents this in memory as a tree of connected nodes:

DOM Tree Representation
Document (Root Node)
└── main (Element Node)
    ├── h1 (Element Node)
    │   └── "Learn Computer Science" (Text Node)
    │
    └── p (Element Node)
        └── "From computers to AI." (Text Node)

Within this hierarchy:

  • main is an Element Node
  • h1 and p are child Element Nodes
  • The inner text strings are distinct Text Nodes

The browser engine allocates these nodes as native C++ (or Rust) heap objects linked by parent, child, and sibling pointers.

5. Why the DOM is Important

The DOM is not just an internal private memory record; it is exposed as a standardized public API to client scripts.

JavaScript uses this object model to inspect, traverse, and modify the document in real time:

// Find the h1 element node in the live DOM tree
const title = document.querySelector("h1");

// Mutate its text node in place
title.textContent = "Welcome to BitBotLab";

The moment JavaScript changes a DOM node, the browser engine flags the document structure as dirty and schedules visual updates.

The DOM acts as the programmatic bridge between static HTML markup and dynamic JavaScript logic.

6. But the DOM Alone is Not Enough

With the DOM tree constructed, the browser knows every element that exists on the page and how they relate hierarchically.

However, the browser still knows nothing about their visual appearance:

  • What font family and font size should the heading use?
  • Is the paragraph text color dark navy, slate, or crimson?
  • What is the calculated width and height of each block?
  • How much margin and padding surrounds each box?
  • Where should elements be positioned on the viewport?

All styling and layout rules originate from CSS.

7. CSS Parsing and CSSOM

Just as it parses HTML, the browser parses all linked, embedded, and inline CSS style rules:

body {
  font-family: Arial, sans-serif;
}

h1 {
  color: #2563eb;
  font-size: 40px;
}

The browser constructs another dedicated tree structure capturing these style declarations:

CSSOM — CSS Object Model
CSSOM Tree Representation
CSSOM Root
│
├── body: { font-family: "Arial, sans-serif" }
│
└── h1: { color: "#2563eb", font-size: "40px" }

Remember this essential distinction:

DOM → Document Structure (The Skeleton)
CSSOM → Styling Rules (The Visual Blueprint)

8. How the Browser Combines DOM and CSSOM

At this stage, the browser holds two distinct blueprints in memory:

DOM Tree
Page Structure
+
CSSOM Tree
Style Declarations

Now the browser must resolve the central styling question:

"Which specific CSS rules apply to which specific DOM node?"

It traverses the DOM nodes, matches selector patterns, and applies cascading hierarchy, inheritance, and specificity calculations to produce a visual synthesis: the Render Tree.

9. What is the Render Tree?

The Render Tree represents:

The visual-only representation of elements that will actually be painted onto the user's screen, combined with their computed CSS styles.

Crucially, the DOM tree and the Render Tree are NOT identical:

  • Non-visual nodes such as <head>, <meta>, <script>, and <title> reside in the DOM, but are entirely omitted from the Render Tree because they occupy no physical pixels.
  • Elements styled with display: none are excluded from the Render Tree completely:
.hidden-modal {
  display: none;
}

Even though .hidden-modal exists as a valid node inside the DOM, neither it nor its children appear in the Render Tree.

(Note: In contrast, elements with visibility: hidden or opacity: 0 DO remain in the Render Tree, because they still consume physical space in the layout.)

10. Now the Browser Must Compute Geometry

The browser now knows which elements are visible and what computed colors and fonts apply to them.

Yet one critical question remains unanswered:

"Where exactly on the screen is each element positioned (X, Y), and what are its physical dimensions (Width, Height)?"

Computing these spatial dimensions is the responsibility of the Layout phase (traditionally referred to as Reflow).

11. What is Layout (Reflow)?

Assume the user's browser viewport measures:

Viewport Width = 1200px
Viewport Height = 800px

Given the HTML nodes:

<h1>Hello</h1>
<p>Welcome</p>
<button>Start</button>

The Layout engine traverses the Render Tree starting from the root and determines the exact geometric bounding box of every node:

h1: x = 40px, y = 30px, width = 1120px, height = 48px
p: x = 40px, y = 98px, width = 1120px, height = 24px
button: x = 40px, y = 142px, width = 120px, height = 40px

Layout calculations incorporate:

  • Explicit widths, heights, min/max bounds, percentages, and viewport units (vw/vh)
  • Margin, padding, and border thicknesses (The CSS Box Model)
  • Positioning schemes (static, relative, absolute, fixed, sticky)
  • Font metrics, line-heights, and word-wrapping behaviors
  • Parent container flow constraints and Flexbox/Grid alignment algorithms
  • The physical pixel dimensions of the current browser viewport

12. Where Do Flexbox and Grid Fit In?

In our CSS lesson, we explored Flexbox and CSS Grid. Viewed through the lens of the browser rendering pipeline, their true mechanical role becomes crystal clear:

When the engine encounters:

.container {
  display: flex;
  justify-content: space-between;
}

The Layout engine calculates the available free space along the main axis and evenly distributes child box offsets accordingly.

Likewise, with CSS Grid:

.gallery {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

The Layout engine partitions viewport width into three equal fractional tracks and assigns row/column slot coordinates to each item.

Key Takeaway: CSS is far more than decorative coloring; a huge portion of CSS consists of direct geometric instructions for the layout computation engine.

13. Painting: Drawing the Visual Elements

Once Layout completes, the browser knows the exact coordinate and size of every box on the canvas.

Next comes Paint: converting those geometric boxes into actual drawing instructions.

The browser records visual command lists (Paint Records):

  • Fill this rectangle with background color #ffffff or a linear gradient
  • Stroke an outline with an 8px border-radius curve
  • Draw text glyphs using the loaded font metrics at specified coordinates
  • Generate box-shadow and text-shadow blurs
  • Decode incoming image buffers and blit them into designated viewports

14. Does the Browser Draw Directly Onto the Screen?

This is where modern browser architecture introduces an elegant engineering optimization.

Browsers do not paint everything in a single pass directly onto the display glass. If they did, scrolling or minor updates would cause horrific screen flickering and sluggish frame rates.

Instead, modern engines (such as Chrome's Blink and Safari's WebKit) decouple rendering into discrete phases:

Modern Rendering Architecture Pipeline
HTML → DOM • CSS → CSSOM • Render Tree • Layout • Paint • Rasterization • Compositing • Screen Pixels

15. What is Rasterization?

Prior phases operate primarily on abstract vector shapes, geometry, text glyphs, and drawing commands.

However, computer screens and mobile displays only understand one fundamental entity: Physical Pixels arranged in a grid matrix.

Rasterization is the computational process of translating visual drawing instructions into an actual array of RGBA color bitmap values in memory.

"Which specific physical pixels on the screen should light up, and in what precise colors?" — That is rasterization.

Modern browsers divide large pages into tiles and employ hardware-accelerated GPUs (Graphics Processing Units) to rasterize tiles with extreme speed.

16. What is Compositing?

In a modern web page, elements do not all sit on a single flat sheet of paper. Content is partitioned across multiple distinct Compositing Layers:

  • The primary page document and base content in one background layer
  • A fixed top navigation bar (position: fixed) in an independent layer
  • A hardware-accelerated <video> or WebGL <canvas> element in its own layer
  • Elements animated using transform: translate3d() or opacity promoted to dedicated GPU surfaces

The browser rasterizes these layers independently into GPU textures. Then, a dedicated, non-blocking Compositor Thread instructs the GPU to composite (stack and blend) these textures onto the final screen buffer.

This process is called: Compositing.

Why Compositing is Revolutionary

When a user scrolls the page or opens an animated slide-in drawer, the browser does not need to recalculate layout or repaint pixels! The Compositor Thread simply instructs the GPU to translate the existing layer texture across the viewport. This delivers silky-smooth 60fps or 120fps animations with zero main-thread CPU overhead.

17. The Complete Pipeline Together

Here is the continuous narrative of how a web page journeys from server transmission to physical display pixels:

The Critical Rendering Path Flow
User enters URL / clicks link
↓
Browser receives resources (HTML, CSS, JS)
↓
HTML Parsing → DOM Tree
CSS Parsing → CSSOM Tree
↓
Style Resolution → Render Tree
↓
Layout / Reflow (Geometry & Coordinates)
↓
Paint (Drawing Instructions)
↓
Rasterization (Bitmap Pixels)
↓
Compositing (GPU Layer Stacking)
↓
PHYSICAL SCREEN PIXELS

18. Where Does JavaScript Enter the Picture?

Having explored JavaScript in the previous lesson, you may ask: "Where exactly does JavaScript sit in this pipeline, and what triggers re-rendering?"

JavaScript can trigger re-evaluation at various pipeline entry points, depending on what it mutates:

1. Mutating the DOM: document.querySelector("h1").textContent = "Hello";

Modifies the DOM tree. The corresponding node in the Render Tree updates, requiring new text drawing commands.

2. Modifying Geometry / Dimensions (Most Expensive): element.style.width = "500px";

Changes element geometry. Surrounding elements shift, forcing the browser to re-execute Layout → Paint → Composite.

3. Modifying Paint-Only Properties: element.style.color = "red";

Does not alter geometry or box boundaries. The browser intelligently skips the Layout phase and proceeds directly to Paint → Composite.

4. Composite-Only Transformations (Fastest): element.style.transform = "translateX(50px)";

Bypasses both Layout and Paint completely! The Compositor thread delegates translation straight to the GPU texture buffer.

19. Why This Matters for Web Performance

Ignorance of the rendering pipeline is the leading cause of sluggish, unresponsive web applications.

If an unoptimized script repeatedly:

  • Alternates between writing and reading DOM geometric properties inside loops (Layout Thrashing)
  • Creates or removes thousands of heavy DOM nodes unnecessarily
  • Performs heavy computational algorithms on the browser's Main Thread

The browser is forced to constantly invalidate and recalculate layouts and repaints. This leads directly to:

  • Stuttering, dropped animation frames
  • Janky, unresponsive touch and mouse scrolling
  • Delayed feedback when users click buttons or submit forms

20. Why 60 FPS? The 16.67ms Budget

For animations and user interactions to feel fluid to the human eye, displays refresh at 60 frames per second (FPS) (or 120 FPS on high-refresh screens).

Consider the mathematical budget:

1 second = 1,000 milliseconds (ms)
1,000 ms ÷ 60 frames ≈ 16.67 milliseconds per frame

Within this tight 16.67ms window, the browser must execute JavaScript, evaluate CSS rules, compute layout geometry, paint drawing records, and composite the frame to the GPU.

If your JavaScript script consumes 20ms by itself, the browser misses its presentation deadline. A frame is dropped, resulting in noticeable jank.

21. Does the Browser Always Re-render the Entire Page?

No, absolutely not.

A common beginner misconception is: "Whenever any CSS property changes, the browser must re-render the entire website from scratch."

In reality, modern rendering engines rely on sophisticated optimizations:

  • Partial Updates & Invalidation Rectangles: The browser tracks bounding boxes of changed nodes and only repaints the specific invalid region.
  • Layer Caching: Static content layers are cached as reusable GPU textures.
  • Hardware Acceleration: Offloading compositing and transforms to the GPU hardware pipeline.

22. JavaScript Engine vs Rendering Engine: Two Distinct Subsystems

Understanding browser architecture requires distinguishing between these two foundational engines:

Rendering Engine

Blink, WebKit, Gecko

Parses HTML and CSS, builds DOM and CSSOM, calculates layout reflow, and generates visual paint records.

JavaScript Engine

V8, JavaScriptCore, SpiderMonkey

Compiles JavaScript source into native machine code (JIT) and manages variables, call stacks, and heap memory.

23. The Relationship with the Browser Event Loop

A vital architectural fact: in modern browsers, the JavaScript Engine and the Rendering Pipeline typically share the exact same Main Thread!

They coordinate harmoniously through the Browser Event Loop:

User Action (Click / Keydown / Scroll)
↓
Hardware Input Event Dispatched
↓
JavaScript Event Handler Runs (Call Stack)
↓
DOM / State Mutation Recorded
↓
Style → Layout → Paint → Composite
↓
New Display Frame Presented

24. A Real-World Walkthrough: The Button Click

Let us trace what occurs within the browser when a user clicks a button to toggle a navigation drawer:

<button id="menuButton">Menu</button>
<div id="menu">Navigation Items</div>
/* CSS */
#menu { display: none; }
#menu.open { display: block; }
// JavaScript
menuButton.addEventListener("click", () => {
  menu.classList.toggle("open");
});

Here is the exact chain of events:

  1. The user clicks the button on their screen.
  2. The operating system transmits an input interrupt to the browser process.
  3. The JavaScript callback runs, adding the open class to #menu.
  4. The computed style of #menu switches from display: none to display: block.
  5. Previously omitted, #menu is now inserted as an active node in the Render Tree!
  6. The presence of a new block element disrupts page geometry; the browser triggers Layout (Reflow).
  7. Background colors, text glyphs, and borders for the menu are converted into Paint instructions.
  8. The Compositor Thread updates layer textures on the GPU, and the open menu instantly appears.

25. The Interplay Between Networking and Rendering

A web browser does not finish networking before starting rendering; the two run concurrently in an interleaved, streaming architecture:

URL Entered → DNS Lookup → TCP + TLS Handshake
↓
HTTP Request → First HTML Byte Stream Arrives
↓
HTML Parser Discovers <link rel="stylesheet"> & <script>
↓
Network Engine Issues Parallel Requests for CSS, JS, Fonts & Images
↓
CSSOM Assembled + Scripts Executed → Progressive Rendering Begins

26. Why Some Websites Render Content Incrementally

You have likely noticed this phenomenon: when loading a content-heavy website, basic typography appears first, images pop in a moment later, custom web fonts swap in (FOUT/FOIC), and eventually interactive widgets become clickable.

This happens because the browser practices Progressive Rendering. Rather than waiting seconds for every high-resolution asset to finish downloading, it renders available content as soon as early pipeline stages complete.

27. The Browser as an Operating Environment

Reflecting on everything we have covered, it becomes evident that a modern web browser is far more than a simple document viewer.

The browser is effectively an Application Operating Environment running inside your operating system:

Network Stack
HTML/CSS Parsers
JS Runtime Engine
GPU 2D/3D Engine
Client Storage (IDB)
Security Sandbox
Hardware Accel
Input & Audio Engine

28. The Complete Architectural Diagram

The diagram below consolidates the full browser rendering architecture:

                    WEB SERVER
                        │
                        │ HTTP Stream
                        ▼
                    ┌─────────┐
                    │ Browser │
                    └────┬────┘
                         │
              ┌──────────┼──────────┐
              │          │          │
             HTML       CSS        JS
              │          │          │
              ▼          ▼          ▼
             DOM       CSSOM    JS Engine
              │          │          │
              └──────┬───┴──────┬───┘
                     │          │
                     ▼          │
               Style / Layout   │
                     │          │
                     ▼          │
                  Paint         │
                     │          │
                     ▼          │
               Rasterize        │
                     │          │
                     └────┬─────┘
                          ▼
                    Compositing
                          │
                          ▼
                       Pixels
                          │
                          ▼
                       SCREEN

29. Core Takeaways from this Lesson

Commit these fundamental equations to memory:

HTML → DOM Document structure and hierarchical node tree
CSS → CSSOM Styling rules and cascaded inheritance tree
DOM + CSSOM → Render Tree Only nodes that visibly appear on screen
Layout (Reflow) Geometry: precise coordinates (X, Y) and box dimensions
Paint Drawing commands for colors, text glyphs, borders, shadows
Rasterization Converting draw commands into pixel bitmap memory arrays
Compositing GPU stacking and blending of independent layer surfaces
Pixels → Screen Physical light emitted by the display hardware

30. What Actually is a Web Page?

We can now define a modern web page with technical precision:

A web page is not a passive HTML text file. It is an active Processing Pipeline:

Network → HTML → DOM → CSS → Style → Layout → Paint → Pixels

And when interactive software runs on top of it, an ongoing feedback loop operates:

JavaScript → Events → State / DOM Changes → Re-rendering

This scientific foundation empowers developers not merely to write code, but to accurately predict and optimize browser execution behavior.

Knowledge Check — The Browser Rendering Pipeline

Test your understanding with these three core conceptual questions:

1. What is the fundamental difference between the DOM tree and the Render Tree?

2. When creating animations, which CSS properties avoid both Layout and Paint by running directly on GPU Compositing layers?

3. To maintain a smooth 60 FPS presentation rate, approximately how much time does the browser have to render each frame?

What's Coming Next?

Now that we understand HTML, CSS, JavaScript, and how the browser executes its rendering pipeline, one vital question emerges: How does a browser actually execute JavaScript code? What is the Call Stack? What is the Memory Heap? And how does asynchronous code coordinate through the Event Loop? In the next lesson, we delve into: JavaScript Runtime: How Code Actually Executes.