The Critical Rendering Path

Follow the exact steps a browser takes to turn HTML, CSS, and JavaScript into the first visible pixels, and learn why where you place CSS and JS decides how fast a page appears.

Published September 15, 20268 min readBy ACY Partner Indonesia
The Critical Rendering Path cover with a first paint timer chip
300 × 250Ad Space AvailablePlace your ad here

When you type an address and hit Enter, a page appears almost instantly. That “almost” hides a surprising amount of work. The browser does not receive a finished picture from the server. It receives raw text, then assembles that text into something you can actually see, step by step, in a fixed order.

That ordered sequence of steps is called the critical rendering path. Understanding it is one of the best ways to reason about web performance, because once you know what the browser must finish before it can draw anything, you understand why some pages feel snappy and others sit blank for a moment. This article walks through the whole path in plain language, with no prior knowledge assumed.

What “rendering” actually means

Rendering is the process of turning code into pixels on a screen. The server sends your browser three main kinds of ingredients:

  • HTML — the structure and content of the page (headings, paragraphs, images, links).
  • CSS — the styling rules (colors, fonts, spacing, layout).
  • JavaScript — the behavior (things that run, change, or respond to clicks).

None of these is directly viewable. A browser cannot paint a wall of HTML text the way you read it. It has to parse each ingredient, build internal models the rendering engine understands, combine them, calculate where everything goes, and only then fill in the actual colored pixels.

The critical rendering path is the name for that pipeline: the minimum set of steps that must complete before the user sees the first meaningful content.

Step 1: HTML becomes the DOM

The first thing that arrives is the HTML document. The browser reads it character by character and builds a tree called the DOM (Document Object Model).

Think of the DOM as a family tree of the page. The <html> element is at the top. Inside it sit <head> and <body>. Inside <body> sit your headings, paragraphs, and so on, each nested under its parent. Every tag becomes a node, and the nesting in your HTML becomes the parent-child relationships in the tree.

Document
└── html
    ├── head
    │   └── title
    └── body
        ├── h1
        └── p

The important detail for performance: HTML parsing is incremental. The browser does not wait for the entire file to download before it starts building the DOM. It builds as the bytes stream in. That is good news, but as we will see, certain things can interrupt this flow.

Step 2: CSS becomes the CSSOM

While reading the HTML, the browser finds your stylesheets (a <link rel="stylesheet"> tag, or styles written inline). It downloads and parses the CSS into a second tree called the CSSOM (CSS Object Model).

The CSSOM holds every style rule and works out which rules apply to which elements, including inherited values cascading down from parents to children. Just like the DOM, it is a structured model the engine can work with, not raw text.

Here is the part that catches people out: CSS is render-blocking. The browser will not paint the page until the CSSOM is ready. The reasoning is sensible. If it painted the page with no styles and then the CSS arrived a moment later, you would see an ugly flash of unstyled content, then a sudden jump as everything restyled. To avoid that, the browser holds back the first paint until it has the styles in hand.

Render-blocking, not parse-blocking

CSS blocks rendering (drawing pixels), but it does not stop the HTML parser from continuing to build the DOM in the background. The DOM and CSSOM are built in parallel where possible. The block happens at the moment of painting, not while reading the HTML.

The practical takeaway: the more CSS the browser must download and parse before it can paint, the longer the page stays blank. Large, slow-loading stylesheets directly delay first paint.

Step 3: JavaScript can block the parser

JavaScript is the tricky guest. When the HTML parser reaches a plain <script> tag, it stops building the DOM, hands control to the JavaScript engine, waits for the script to download (if it is an external file) and finish running, and only then resumes parsing the HTML.

This is called parser-blocking behavior, and it exists for a real reason. A script might use document.write or otherwise change the page structure on the spot, so the browser cannot safely keep building the DOM while a script that could rewrite it is pending. It waits to be safe.

The consequence is direct. A slow script placed high in the document freezes DOM construction at that point. Everything below the script waits. If your script is in the <head>, the browser may be stuck before it has even reached your visible content.

<head>
  <script src="big-slow-file.js"></script>
</head>
<body>
  <!-- The browser does not build this until the script above finishes -->
  <h1>Hello</h1>
</body>

There is one more wrinkle. If a script wants to read styles (for example, asking how wide an element is), it may need the CSSOM first. So a stylesheet that is still loading can delay a script, which in turn delays the parser. The three ingredients are more tangled than they first appear.

Two attributes that change the picture

Modern HTML gives you two attributes that tell the browser not to block the parser for a script: async and defer.

Attribute Downloads while parsing? Blocks the parser? Runs when?
(none) No, fetched when reached Yes, parser stops and waits Immediately, in place
async Yes, in the background No As soon as it finishes downloading (order not guaranteed)
defer Yes, in the background No After the DOM is fully built, in document order

For most scripts that touch the page content, defer is the friendliest choice: the file downloads quietly alongside parsing and runs once the DOM is ready, in the order you wrote it.

Step 4: Render tree, layout, and paint

Once the browser has the DOM and the CSSOM, it combines them into a render tree. This tree contains only what will actually be displayed. Elements that are hidden with display: none, for instance, are left out, because there is no point measuring something nobody will see.

Next comes layout (sometimes called reflow). Now that the browser knows what to show and how it is styled, it calculates the exact geometry: how big each box is, and where on the screen it sits. This depends on the viewport size, which is why the same page lays out differently on a phone and a desktop.

Finally comes paint. The browser fills in the pixels: text, colors, borders, shadows, images. On complex pages this happens in layers that are then composited together, but the core idea is simple: paint is the moment the page becomes visible.

HTML ─► DOM ─┐
             ├─► Render Tree ─► Layout ─► Paint ─► pixels on screen
CSS  ─► CSSOM ┘

        │  (JavaScript can interrupt anywhere along the way)

Why placement of CSS and JS matters so much

Now the whole point clicks into place. The browser cannot paint until it has both the DOM and the CSSOM, and JavaScript can stall the building of the DOM. So the order and weight of these resources directly control how quickly the first pixels appear. A few clear principles fall out of this:

  • Keep render-blocking CSS lean. The CSS needed to paint the visible top of the page should be small and arrive early. Anything not needed for the first view can load later.
  • Don’t let scripts block the first paint. Use defer (or async where order doesn’t matter) so the parser keeps going. A common older habit is to place scripts just before the closing </body> tag for the same reason: by then the DOM above is already built.
  • Fewer and smaller is faster. Every blocking file the browser must fetch and parse before painting adds delay. Reducing how many there are, and how big they are, shortens the path.

A simple mental test

Before you add a <link> or <script> to the top of your page, ask: “Does the browser need this to draw the first screen?” If yes, keep it small and early. If no, let it load without blocking, so the page can appear while it finishes in the background.

A quick recap

The critical rendering path is the fixed sequence a browser follows to turn code into a visible page:

  1. HTML → DOM — the structure is parsed into a tree, incrementally as it arrives.
  2. CSS → CSSOM — styles are parsed into a tree, and this step is render-blocking; no paint until it’s ready.
  3. JavaScript — plain scripts are parser-blocking; they freeze DOM construction until they finish, unless you use async or defer.
  4. Render tree → layout → paint — the visible elements are combined, measured, and finally drawn as pixels.

Everything you hear about web performance, lazy loading, splitting code, inlining critical styles, deferring scripts, traces back to one goal: shorten this path so the first meaningful pixels arrive sooner.

If you want to go deeper from here, a natural next stop is learning how browsers fetch all those files in the first place over the network, and how caching lets repeat visits skip much of the work entirely. With the rendering path in mind, those topics will feel like pieces of the same picture rather than separate trivia.

Tags:critical rendering pathbrowserperformancedomcssomrendering
728 × 90Ad Space AvailablePlace your ad here

Related Articles

See All Articles

You Might Also Like

Anatomy of a URL — every part of a link
Web Fundamentals / DNS & Domains

Anatomy of a URL

Break a URL into its parts: scheme, host, port, path, query, and fragment. A beginner-friendly tour of what every piece of a web link actually does.

Sep 15, 20268 min read
DNS Propagation cover with a TTL timer ticking down
Web Fundamentals / DNS & Domains

DNS Propagation: Why Changes Take Time

You changed a DNS record but the old site still loads for some people. Here is why DNS changes are not instant, what propagation really means, and how TTL controls the wait.

Sep 15, 202610 min read
DNS Record Types: A, AAAA, CNAME, MX, TXT — cover
Web Fundamentals / DNS & Domains

DNS Record Types: A, AAAA, CNAME, MX, TXT

A beginner-friendly tour of the most common DNS record types and what each one does, with a quick-reference table and plain-language examples you can actually follow.

Sep 15, 20268 min read
Reading a domain: TLD, registrable domain, and subdomain
Web Fundamentals / DNS & Domains

Domains, Subdomains, and TLDs

Learn how to read a web address from right to left: what a TLD is, what the registrable domain is, and how subdomains let you split one site into many. Beginner-friendly and conceptual.

Sep 15, 20267 min read
How DNS Works: The Lookup Journey — the resolver to root to TLD path
Web Fundamentals / DNS & Domains

How DNS Works: The Lookup Journey

Follow a domain name from the moment you press Enter to the IP address that comes back. We trace every cache and server in the DNS lookup chain, step by step, in plain language.

Sep 15, 202610 min read
How Domain Registration Works cover, Web Fundamentals DNS and Domains
Web Fundamentals / DNS & Domains

How Domain Registration Works

A beginner-friendly guide to registering a domain: who the registrars and registries are, what ICANN does, why you rent a name yearly, and how DNS points it at your site.

Sep 15, 20269 min read