The Big Picture: From Recipe to Plated Meal

A web page arrives as plain text: HTML (the structure), CSS (the looks) and JavaScript (the behaviour). The browser has to turn that text into coloured pixels on your screen. The part of the browser that does this is the rendering engine (also called the layout engine).

Think of a restaurant. The page text is a recipe. The rendering engine is the kitchen that reads the recipe, prepares the ingredients, arranges the plate and finally carries it out to the table.

BrowserRendering engine
Chrome, Edge, Opera, BraveBlink (part of Chromium)
SafariWebKit
FirefoxGecko (with newer parts such as Servo-derived code)

All three follow the same web standards, so a page looks nearly the same everywhere. Inside, the steps are similar, and that is what this section describes. We use the shared names, not the code of any one engine.

 text bytes ─► HTML ─► DOM ─┐
                            ├─► render tree ─► layout ─► paint ─► composite ─► screen
 text bytes ─► CSS ─► CSSOM ┘

2.1 HTML Parsing → DOM Tree

What it is: The browser reads the HTML text and builds a tree of objects called the DOM (Document Object Model). A tree here means: one root, with branches, with smaller branches. Every tag becomes a node (one object in the tree).

Here is a tiny page:

<html>
  <body>
    <h1>Hello</h1>
    <p>Welcome to <b>my</b> page.</p>
  </body>
</html>

The parser turns it into this tree:

html
 └─ body
     ├─ h1
     │   └─ text: "Hello"
     └─ p
         ├─ text: "Welcome to "
         ├─ b
         │   └─ text: "my"
         └─ text: " page."

Steps inside the parser (simplified):

StepWhat happens
1. Bytes → charactersThe raw bytes are decoded using the page's text encoding (usually UTF-8).
2. Characters → tokensThe text is cut into pieces such as "start tag p", "text", "end tag p".
3. Tokens → nodesEach token becomes an object.
4. Nodes → treeNodes are linked as parent and child.

HTML parsing is forgiving. If you forget to close a tag, the browser does not give an error. The standard says exactly how to guess what you meant, so every browser repairs bad HTML the same way.

The parser is incremental. The browser does not wait for the whole file. It starts building the DOM as bytes stream in from the network. Also, a small helper (a "preload scanner") looks ahead in the text to start downloading images, CSS and scripts early.

The DOM is alive. JavaScript can read and change the DOM (add a node, change text). When it does, the browser may need to redo work (see 2.4). The DOM is what you see in DevTools' Elements tab.

2.2 CSS Parsing → Style Rules

What it is: CSS (Cascading Style Sheets) says how things should look. The browser parses it into another structure called the CSSOM (CSS Object Model): a collection of rules like "all p elements are 16 pixels tall and dark grey".

 p      { color: grey; font-size: 16px; }
 .big   { font-size: 32px; }
 h1     { color: red; }

Where does CSS come from? There are three places: the browser's own default styles (why a heading is big and bold even with no CSS), the page's linked or embedded CSS, and inline style="..." attributes.

Why "cascading"? Several rules can match one element. The browser picks a winner using clear rules: a more specific rule beats a less specific one, a later rule beats an earlier one, and some properties are inherited from parent to child (a p inside a grey body is grey too). The result for each element is its computed style: the final answer to "what colour, what size, what font?".

You can see computed styles in DevTools: Elements tab, then the Computed pane.

CSS blocks rendering. The browser will not paint anything until it has the CSS it knows about, because painting with the wrong style and then restyling would flash ugly. So CSS is called render-blocking. This is why it is good to keep CSS small and load it early (2.5).

2.3 Render Tree Construction

What it is: The browser combines the DOM and the CSSOM into a render tree (in Chromium terms, roughly the "layout tree"). The render tree has only what will be drawn, each node paired with its final style.

In the DOM...In the render tree?
<p>, <h1>, textYes
<head>, <script>, <meta>No (not visible things)
An element with display: noneNo (removed from the page layout)
An element with visibility: hiddenYes (takes up space but draws nothing)
 DOM (everything)              Render tree (only visible things)

 html                          body
  ├─ head                       ├─ h1 "Hello"
  │   └─ title                  └─ p
  └─ body                           ├─ "Welcome to "
      ├─ h1                         ├─ b "my"
      ├─ p                          └─ " page."
      └─ div (display:none)

This is a simplified picture; real engines keep extra trees and caches. What matters is the idea: structure + style = a list of boxes to draw.

2.4 Layout and Paint

Layout (also called reflow, especially in Firefox terms) is the step that works out where everything goes and how big it is. Start from the window size (the viewport) and walk the render tree: a block of text wraps at the window width, a box is 300 pixels wide, a picture sits below the heading. Each box gets four numbers: x, y, width, height. Because the position of one box depends on the boxes before it (and on their parents), layout can be costly for big pages.

Paint is the step that works out how to draw each box: in what order to draw backgrounds, borders, text and images. Paint produces a list of drawing instructions ("fill this rectangle with white, draw this text here"). Chromium splits the page into layers (like transparent sheets) so that some parts can move without redrawing the rest, for example a scrolling area or an animated menu.

Raster turns those drawing instructions into actual pixels for each layer (often done on the GPU in modern browsers).

Composite combines the layers into the final picture, in the right order, with the right movement. This is done by the GPU process (Section 1) because graphics cards are very good at stacking and moving images. The finished frame goes to the display (Chapter 32, and Section 7.9).

 STAGE        QUESTION IT ANSWERS            COST WHEN REPEATED
 ─────────── ─────────────────────────────── ───────────────────
 Style        Which rules apply to what?      medium
 Layout       Where and how big?              HIGH
 Paint        What does each box look like?   medium
 Composite    Stack layers, move them         LOW  (GPU)

Reflow vs repaint. After the first draw, a page changes all the time (JavaScript edits, hover effects, animations). How much work follows depends on what changed:

What changedWork needed
Size, position, text length, adding or removing an elementLayout again (reflow), then paint, then composite. Slowest.
Only colour, background, shadowPaint again (repaint) and composite. Medium.
Only transform or opacity (on its own layer)Composite only. Fastest, runs on the GPU.

That is why smooth animations prefer transform and opacity: they skip layout and paint.

Frames per second. Most screens refresh at 60 Hz: 60 times a second. One second divided by 60 is about 16.7 milliseconds per frame. To look smooth the browser must do everything (JavaScript, style, layout, paint, composite) for each frame inside that budget. A screen at 120 Hz leaves only about 8.3 ms. If a frame takes too long, the screen shows the old image again: the page stutters (called "jank").

 16.7 ms budget (one frame at 60 Hz)

 |-- JS --|-- style --|-- layout --|-- paint --|-- composite --|
 0 ms                                                      16.7 ms
 Done in time -> smooth.   Late -> a dropped frame -> jank.

2.5 The Critical Rendering Path and Blocking Scripts

What it is: The critical rendering path is the chain of steps between "bytes arrive" and "first pixels appear":

 HTML ──► DOM ───┐
                 ├──► render tree ──► layout ──► paint ──► first pixels
 CSS ───► CSSOM ─┘

Anything that makes this chain wait makes the page appear later.

Why scripts can block it. JavaScript can change both the DOM (add nodes) and the styles. So when the HTML parser meets a plain <script src="app.js"> tag, it must stop, download the script, run it, and only then continue, because the script might change the page. Also a script that asks "what is the size of this box?" forces the browser to finish CSS and layout first.

Script tagBehaviour
<script src="a.js">Blocks the parser while it downloads and runs.
<script src="a.js" async>Downloads in the background; runs as soon as ready (may interrupt parsing). Order is not guaranteed.
<script src="a.js" defer>Downloads in the background; runs after the HTML is parsed, in order.

Tips that follow from this: put CSS early and keep it small; use defer or async for scripts; do not make the page wait for huge images; load only what is needed first. DevTools' Performance tab and the Lighthouse tool (hedge: names and menu positions may change) can show this chain.

Memory link. All these trees and layers live in RAM of the renderer process (Chapter 3 — RAM and Memory Internals). A very large page, thousands of elements or huge images, costs many megabytes.

Summary

TermPlain meaning
Blink / WebKit / GeckoRendering engines of Chrome-Edge / Safari / Firefox
DOMTree of objects built from HTML
CSSOMCollection of style rules built from CSS
Render treeOnly the visible boxes with their styles
Layout (reflow)Working out size and position of each box
Paint / rasterDrawing instructions, then pixels
CompositeGPU stacks the layers into the final frame
Repaint vs reflowReflow redoes layout (slow); repaint only redraws (cheaper)
60 HzAbout 16.7 ms per frame to stay smooth
Critical rendering pathSteps from bytes to first pixels
Render-blockingCSS and plain scripts that make the page wait