Parsing and the Render Tree
Before a pixel is painted, the browser parses HTML into the DOM and CSS into the CSSOM — then merges them into a render tree that contains only what will actually be painted.
- Describe how the browser turns an HTML byte stream into a DOM tree
- Explain what the CSSOM is and why CSS blocks rendering
- Trace the path from DOM + CSSOM to a painted frame
- Distinguish layout, paint, and compositing as separate pipeline steps
You have written HTML and CSS for a while. But what does the browser actually do between receiving the first byte and lighting up a pixel? The answer is a five-step pipeline, and knowing each step tells you exactly why certain performance techniques work and others do not.
Step 1 — parsing HTML into the DOM
The browser receives HTML as a raw byte stream. Its HTML parser reads that stream from top to bottom, tokenising tags, attributes, and text content into nodes, and linking those nodes into a tree:
document
└── html
├── head
│ ├── meta (charset)
│ └── link (stylesheet)
└── body
├── h1 "Hello"
└── p "World"This tree is the DOM. Every element, text node, and comment in your HTML becomes a node in it. JavaScript reads and modifies the DOM at runtime; the browser uses it as the source of truth for everything that follows.
One important detail: the parser is streaming. It does not wait for the
entire file to arrive before building nodes — it builds as bytes arrive. That is
why content higher in the HTML appears on screen sooner. It is also why a
<script> tag in <head> can stall the process (more on that in the Critical
Rendering Path lesson).
Step 2 — parsing CSS into the CSSOM
In parallel (or as soon as a <link rel="stylesheet"> is encountered), the
browser fetches and parses your stylesheets. The output is the CSSOM — a separate tree of style rules, one per selector,
with inheritance and cascade already resolved:
body → { font-family: sans-serif; color: #222 }
h1 → { font-size: 2rem; color: inherit }
p → { margin-top: 1em }Unlike the DOM, the CSSOM is not built incrementally. The browser must finish parsing all CSS before it can know the computed style of any element — because a rule in a later stylesheet can override an earlier one. This is the source of CSS's render-blocking behaviour: the browser will not proceed to the next step until every stylesheet has been downloaded and parsed.
An inline <style> block in <head> is available immediately — no network
round-trip required. That is why inlining small amounts of critical CSS is a
legitimate performance technique.
Step 3 — building the render tree
Once both trees exist, the browser merges them into the render tree. The render tree keeps only what will actually be drawn:
- Elements with
display: noneare excluded entirely (they take up no space and produce no pixels). visibility: hiddenelements are included — they occupy space but are drawn transparently.- Pseudo-elements like
::beforeand::afterare included even though they have no DOM node.
Each node in the render tree carries the fully computed style for that element: resolved font sizes, pixel values for lengths, final colours after cascade and inheritance.
Step 4 — layout
With the render tree built, the browser walks it and calculates the exact
position and size of every box. This is called layout (or historically,
reflow). The output is a set of coordinates: "this <h1> starts at (16, 80)
and is 600px wide and 48px tall."
Layout is relative to the viewport, so it happens again whenever the window is resized, or whenever a DOM or style change affects geometry.
Step 5 — paint and compositing
Paint fills in the pixels — text glyphs, background colors, borders, box shadows, images. The browser may split the page into independent layers (a technique called promotion) and paint each layer separately.
Compositing then hands those layers to the
GPU, which overlays them into the final image you see. Properties like
transform and opacity live entirely on the compositor thread — they can be
animated without touching the CPU's layout or paint steps.
Byte stream → DOM
↓
Stylesheet → CSSOM
↓
Render tree
↓
Layout
↓
Paint
↓
Compositing → pixels on screenWhere to go next
You now have a mental model of the full pipeline. Next: Reflow and Repaint — what happens when JavaScript or user interaction triggers a change mid-page, and why some changes are far more expensive than others.
Lab — Accessibility Audit
Run an automated audit on a provided broken page, then complete a keyboard and screen-reader test and fix the identified issues.
Reflow and Repaint
Reflow recalculates geometry for all affected elements — an expensive operation triggered by DOM or style changes that affect layout.