Lesson 11 of 26
The Critical Rendering Path
What the browser must finish before the first pixel appears, why render-blocking resources exist, and the concrete techniques that shorten that path.
Between "the browser receives HTML" and "a user sees a pixel on screen" is a specific, well-defined sequence of work called the critical rendering path. Understanding it precisely — not just "make the page fast" as a vague goal — is what turns performance work from guesswork into a checklist of concrete, targeted fixes.
The path itself
- Step 1
Parse HTML into the DOM
The browser reads HTML top to bottom, building the document tree as it goes.
- Step 2
Parse CSS into the CSSOM
Every stylesheet the browser encounters is fetched and parsed into a tree describing computed styles.
- Step 3
Combine into the render tree
DOM and CSSOM are merged into the tree of visible elements, with their computed styles — elements with display: none are excluded here.
- Step 4
Layout
The browser computes the exact size and position of every element in the render tree.
- Step 5
Paint
Pixels are actually drawn to the screen based on the layout — this is the moment something becomes visible.
The reason this matters practically is that certain resources block this path from proceeding, and knowing which ones — and why — is what tells you where to actually intervene.
What blocks the path, and why
CSS blocks rendering. The browser refuses to paint anything until it
knows how every element should look, to avoid a flash of unstyled content.
A <link rel="stylesheet"> in the head, especially a large one or one served
slowly, directly delays first paint.
Synchronous <script> tags block HTML parsing. A plain script tag with
no async or defer stops the DOM from being built further at that exact
point in the document — the browser fetches, parses and executes it, then
resumes. Placed early in the document, before the content that actually
needs to render, this can meaningfully delay everything downstream.
Fonts can cause a second, separate delay — even after paint, custom web
fonts loading late can trigger a layout shift (or invisible text, depending
on the font-display strategy) as text re-flows once the real font arrives.
The concrete levers
defer and async on scripts. defer downloads the script in parallel
with parsing but delays execution until parsing finishes, preserving order
relative to other deferred scripts — the standard choice for scripts that
need the DOM but don't need to block rendering. async downloads in
parallel and executes the moment it's ready, with no ordering guarantee
relative to other scripts — appropriate for independent scripts like
analytics that don't depend on, or get depended on by, anything else.
Critical CSS inlining. Extracting just the styles needed for the
above-the-fold, initial view and inlining them directly in the HTML
<head> means the browser doesn't wait on a separate network round-trip for
those specific styles — the rest of the stylesheet can load afterward
without blocking that first paint.
Resource hints — <link rel="preload"> for a resource you know is
critical and would otherwise be discovered late (a hero image, a key font),
and <link rel="preconnect"> for an origin you're about to fetch from, so
the DNS lookup and TLS handshake happen ahead of the actual request.
Minimizing render-blocking resources generally — fewer synchronous
stylesheets, moving non-critical CSS to load asynchronously (via a technique
like media="print" swapped after load, or a dedicated loader), and keeping
whatever must block the path as small as possible.
Why this framing matters in an interview
"Make it faster" is not an actionable answer. "The critical rendering path is blocked by a large synchronous stylesheet and two head-placed scripts with no defer — inline the critical CSS, defer the scripts, and load the rest of the stylesheet asynchronously" is a specific, defensible plan that demonstrates you know exactly which browser mechanism you're targeting and why it moves the needle on first paint specifically — as distinct from other performance metrics like interactivity, covered elsewhere in this stage.
What to remember
- The critical rendering path is DOM + CSSOM → render tree → layout → paint, and nothing paints until layout can run, which needs both the DOM and CSSOM ready.
- CSS is render-blocking by default; a plain, un-deferred script is parser-blocking — both delay first paint, for different reasons.
defer,async, critical CSS inlining, and resource hints (preload,preconnect) are the concrete levers for shortening this specific path.- Diagnosing "what's slow" starts with naming which stage of this path is blocked and by what, not a vague sense that the page feels slow.
Check yourself
3 questions · pass 3/3 to unlock Code-Splitting and Bundle Budgets
1.Why does a
<link rel="stylesheet">in the<head>block the browser from painting anything, by default?2.A page has a
<script>tag with nodeferorasyncattribute, placed in the<head>. What does this do to the critical rendering path?3.What's the practical benefit of inlining a small amount of 'critical' CSS directly in the HTML
<head>, with the rest loaded separately?
3 left to answer