Lighthouse audit render-blocking-insight · Performance

Eliminate render-blocking resources: what it is and how to fix it

View raw .md for LLMs / your notes
Quick answer: Render-blocking resources are CSS and synchronous scripts in the head that the browser must process before painting anything. Eliminate them by inlining critical above-the-fold CSS, loading the rest non-blocking, and adding defer or async to scripts. This usually improves both First and Largest Contentful Paint.

The browser can't render anything until it finishes downloading and parsing every render-blocking CSS and synchronous JS in the <head>. Each blocking resource adds latency to FCP and LCP.

TL;DR

What is render blocking?

Render blocking is when the browser has to stop building the page and wait for a file to download and process before it can paint anything on screen. The browser parses your HTML from top to bottom, and certain resources in the <head> halt that parse until they finish. Nothing is visible to the user while that wait happens, which is why render-blocking resources are the most common cause of a slow First Contentful Paint.

What is a render-blocking script? A <script> tag in the <head> without a defer or async attribute. The browser must download it, execute it, and only then continue parsing the HTML, because the script could modify the document.

What is render-blocking CSS? Any <link rel="stylesheet"> without a media condition. CSS is render blocking by design: the browser refuses to paint until it knows the styles, so it cannot show unstyled content and then restyle it.

The distinction that matters: render blocking is not the same as slow. A 200 KB stylesheet that loads in parallel with nothing waiting on it costs you nothing visually. The same file in the <head> costs you your entire first paint. Position and attributes decide whether a resource blocks, not size.

What does the render-blocking-resources audit check?

Lighthouse identifies every CSS link tag and synchronous <script> in <head> that delays the first paint. It estimates how much time you'd save by deferring each one.

Why do render-blocking resources matter?

The browser parses HTML top-down. When it hits:

<link rel="stylesheet" href="big-app.css" />

…it stops, downloads big-app.css, parses it, then continues. If your CSS is 200 KB on a slow network, that's a 1-2 second pause before any pixels paint. Same for synchronous JS in <head>.

How do I check for render-blocking resources?

You do not need a dedicated checker tool. Three reliable ways:

  1. PageSpeed Insights or Lighthouse: run the audit and open "Eliminate render-blocking resources" under Opportunities. It lists every blocking file with its URL, transfer size, and the estimated milliseconds you would save by deferring it. That list is your fix queue, already ranked.
  2. Read your own <head> in view-source. Every <link rel="stylesheet"> without a media attribute and every <script> without defer or async is render blocking. This takes about thirty seconds and catches most of it.
  3. Chrome DevTools Network panel: load the page, sort by start time, and look at what completes before first paint. Anything downloading in that window while nothing renders is in the critical path.

The DevTools Coverage tab is a useful companion: it shows how much of each blocking stylesheet the page actually uses. A stylesheet that blocks first paint and is 90% unused is the highest-value thing on the list.

How do I eliminate render-blocking resources?

1. Inline critical CSS

"Critical CSS" = the styles needed to render the above-the-fold portion of the page. Inline it directly in <head>:

<head>
  <style>
    /* critical: header, hero, primary nav */
    body { margin: 0; font-family: system-ui; }
    header { padding: 16px; background: #fafaf9; }
    h1 { font-size: 2rem; }
  </style>
  <link rel="preload" as="style" href="/full.css" onload="this.rel='stylesheet'" />
</head>

For larger sites, tools like Critical, Penthouse, or framework features (Next.js does this automatically in some configurations) extract critical CSS at build time.

2. Defer non-critical CSS

<!-- WRONG: blocks rendering -->
<link rel="stylesheet" href="/non-critical.css" />

<!-- RIGHT: load asynchronously, apply after parse -->
<link rel="preload" as="style" href="/non-critical.css" onload="this.rel='stylesheet'" />
<noscript><link rel="stylesheet" href="/non-critical.css" /></noscript>

The onload swap converts the preload into a stylesheet once it's loaded, without blocking. The <noscript> fallback ensures JS-disabled users still get styles.

3. Add defer or async to scripts

<!-- WRONG: blocks the parser -->
<script src="app.js"></script>

<!-- defer: runs after document parse, preserves order -->
<script src="app.js" defer></script>

<!-- async: runs whenever it's downloaded (no order guarantee) -->
<script src="analytics.js" async></script>

Rule of thumb:

4. Load fonts strategically

Web fonts are a common silent render-blocker. Best practice:

<head>
  <!-- preconnect to the font origin so DNS/TLS is warm -->
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />

  <!-- preload the most critical font file (typically the body font) -->
  <link rel="preload" as="font" type="font/woff2"
        href="https://fonts.gstatic.com/.../inter.woff2" crossorigin />

  <!-- load the CSS asynchronously -->
  <link rel="preload" as="style"
        href="https://fonts.googleapis.com/css2?family=Inter"
        onload="this.rel='stylesheet'" />
</head>

Or self-host fonts and use font-display: swap so text renders with a fallback font immediately.

What are common render-blocking mistakes?

How do I verify render-blocking is fixed?

  1. Re-run Lighthouse, render-blocking-resources audit should pass or show much smaller estimated savings.
  2. Check first-contentful-paint and largest-contentful-paint audits, both should improve.
  3. DevTools → Network → throttle to Slow 3G → reload. The page should paint within ~1-2 seconds even on slow connections.

Audit your URL at https://lighthouse-md.com.

Audit your page now

Paste your URL, get scores plus a CLAUDE.md plan for Claude Code.

Run audit →