Front Runner Front End Web Development Blog

Critical Rendering Path Example Explained

A clear critical rendering path example for front-end developers, with step-by-step browser behaviour and practical ways to improve page load speed.

| June 29, 2026 | 8 min read

A page can look slow even when the server did its job perfectly. That usually stings a bit, especially when DevTools is sitting there quietly judging you. A solid critical rendering path example helps explain why this happens, because the bottleneck is often not the network alone – it is the order the browser must follow before anything useful appears on screen.

If the term sounds a bit abstract, think of it as the browser’s to-do list for turning HTML, CSS and JavaScript into visible pixels. The critical rendering path is the sequence of steps required to render the initial view of a page. If one of those steps gets blocked, your user stares at a blank screen and starts making life choices.

A simple critical rendering path example

Imagine a browser requests this page:

“`html Shop

New Trainers

Lightweight running shoes for everyday miles.

Blue running shoe

“`

And the CSS looks like this:

“`css body { font-family: sans-serif; margin: 0; }

header { background: navy; color: white; padding: 2rem; } “`

At first glance, that page is tiny. Surely it should render instantly. Not necessarily. The browser still has a strict process to follow.

Step 1: Download the HTML

The browser receives the HTML response and starts parsing it from top to bottom. As it parses, it builds the DOM, or Document Object Model. That is basically the browser’s internal representation of the page structure.

So far, so good. It sees the `html`, `head`, `body`, `header`, `h1`, `main`, `p`, and `img` elements and starts assembling that tree.

Step 2: Discover render-blocking resources

While parsing the `head`, the browser encounters this line:

“`html “`

That stylesheet is critical for rendering. The browser can keep parsing the HTML, but it cannot safely paint the page until it has the CSS and knows how elements should look. Without that, it risks showing unstyled content and then repainting everything a moment later.

Then it finds this line:

“`html “`

This is where things often get awkward. A normal script in the head can block HTML parsing because the browser must download and execute it before continuing. Why? Because JavaScript can change the DOM or even inject more CSS. The browser does not want to guess and render the wrong thing.

Step 3: Build the CSSOM

Once `styles.css` is downloaded, the browser parses it into the CSSOM, or CSS Object Model. This is the style equivalent of the DOM.

The browser now knows that the `header` should have a navy background and white text, and that the `body` uses a sans-serif font with no default margin.

Step 4: Combine DOM and CSSOM into the render tree

The browser merges the DOM and CSSOM to create the render tree. This tree includes only what needs to be rendered. It does not care about every node in the raw HTML in the same way. It cares about visible content and the styles attached to it.

At this point, the browser knows what to draw and how it should look.

Step 5: Layout

Next comes layout, sometimes called reflow. The browser calculates where elements should appear and how much space they take up. It works out the size and position of the header, paragraph and image.

This step depends on viewport size, CSS rules, fonts and content dimensions. A small change can ripple through the layout, which is why layout work can get expensive on more complex pages.

Step 6: Paint

Finally, the browser paints pixels to the screen. Backgrounds, text, borders and images are drawn. Your user sees the page.

That is the critical rendering path in motion. Not glamorous, but extremely relevant when your page feels oddly sluggish.

Where this critical rendering path example goes wrong

The example above has two common issues. First, the stylesheet blocks rendering. That is normal and often necessary, but it means CSS delivery matters a lot. Secondly, the script in the head blocks parsing, which can delay everything that follows.

If `app.js` is large, fetched from a slow origin, or full of work that is irrelevant to the first screen, the page can sit there doing nothing visible. The browser is not broken. It is just obedient.

Now imagine `styles.css` is 300 KB and includes every style for the whole site, including pages the user is not even visiting. That is a lot of CSS to download and parse before painting a simple heading and paragraph. Classic front-end move. We have all been there.

Improving the example without getting weird about it

A better version of the page might look like this:

“`html Shop body { font-family: sans-serif; margin: 0; } header { background: navy; color: white; padding: 2rem; }

New Trainers

Lightweight running shoes for everyday miles.

Blue running shoe

“`

This changes the path in a few useful ways.

Inlining a small amount of critical CSS allows the browser to style the above-the-fold content immediately. That means the first view can render before the full stylesheet finishes loading. Using `defer` on the script tells the browser to download it in parallel but wait to execute it until after HTML parsing is complete. Much less dramatic.

That said, there are trade-offs. Inlining too much CSS bloats the HTML response and makes caching less effective. Preloading assets can help, but overusing preload is a nice way to turn resource prioritisation into chaos. Every optimisation has a cost if applied without restraint.

What actually blocks rendering

For practical front-end work, you mainly care about a few things.

CSS is render-blocking by default because the browser needs styles before painting. JavaScript can be parser-blocking and indirectly render-blocking, especially when loaded synchronously in the document head. Web fonts can also delay text rendering depending on how they are loaded and the browser’s font display behaviour. Large images usually do not block the first paint in the same way CSS does, but they can still delay meaningful content if they dominate the viewport.

This is why performance work is often a prioritisation problem rather than a pure file-size problem. A 50 KB file can be more harmful than a 200 KB file if it sits directly on the critical path.

How to spot the critical rendering path in DevTools

If you are trying to understand a real page, open DevTools and inspect the Network and Performance panels. Look at request ordering, resource priority and when the first paint happens.

If your CSS arrives late, your page may remain blank longer than expected. If a script in the head starts early and finishes late, that is a red flag. If layout or style recalculation spikes after load, you may have JavaScript triggering extra rendering work.

Lighthouse can point out render-blocking resources, but use it as a clue, not gospel. Sometimes a resource is technically render-blocking because it should be. The issue is not that it blocks. The issue is whether it deserves to.

Practical ways to shorten the path

For most front-end developers, the best improvements are boring in the best way. Keep critical CSS small. Defer or async non-essential JavaScript. Reduce unused CSS and JavaScript. Compress files. Serve modern image formats. Avoid layout thrashing in early scripts. Make sure fonts are loaded sensibly.

Also, be realistic about framework output. If your build process ships a mountain of CSS and hydration code for a tiny landing page, the browser still has to deal with that mountain. Fancy tooling does not exempt you from physics.

Why this matters beyond page speed scores

A faster critical rendering path improves more than a metric. It changes how a page feels. Users get visual feedback sooner, which makes the site feel responsive and trustworthy. That matters whether you are building a shop, a docs site or your portfolio that you swear you will update this weekend.

For junior developers, understanding this path is especially useful because it turns performance from vague advice into a series of concrete decisions. Should this script be deferred? Does this CSS need to block rendering? Can the first screen be styled with less code? Those are answerable questions.

Once you can walk through a critical rendering path example step by step, real-world debugging gets much easier. You stop treating slow rendering like browser magic and start seeing the actual chain of events. And that is usually the point where performance work becomes less intimidating and a lot more effective.

The next time a page feels slow, do not just ask how big the files are. Ask what the browser must do before it can paint anything useful. That question tends to lead you to the fix far quicker than wishful thinking and another round of minifying everything in sight.

Post Tags