Scanverra

How to Fix Render-Blocking Resources

Before the browser paints a single pixel, it has to finish downloading and parsing every stylesheet and synchronous script in your <head>. The more of those there are, the longer the page sits blank.

Why the Browser Waits

CSS is render-blocking by design - the browser can't safely paint content it doesn't yet know the final styles for, so it holds off until every stylesheet in the document (that applies to the current viewport) has downloaded and parsed. A synchronous <script> tag blocks the HTML parser itself - parsing stops, the script downloads and executes, and only then does parsing resume.

How to Fix It

1. Defer non-critical JavaScript

defer lets the parser continue; the script still runs in document orderhtml
1<script src="/analytics.js" defer></script>

2. Inline critical, above-the-fold CSS

Extract just the CSS needed to render what's visible without scrolling, inline it directly in the <head>, and load the full stylesheet asynchronously:

Load the full stylesheet without blocking initial renderhtml
1<style>/* critical, above-the-fold CSS inlined here */</style>
2<link rel="preload" href="/styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'" />
3<noscript><link rel="stylesheet" href="/styles.css" /></noscript>

3. Scope non-critical stylesheets with a media attribute

A print stylesheet shouldn't block the screen renderhtml
1<link rel="stylesheet" href="/print.css" media="print" />

4. Move scripts that don't need to run early to the end of the body

If a script genuinely doesn't need defer's guarantees, placing it just before </body> means the parser has already processed everything above it before it blocks.

5. Let your framework's build step split and prioritize automatically

Modern framework build tooling (Next.js, Vite) already code-splits and defers non-critical JS by default in most configurations - a render-blocking finding is often a sign of a manually-added third-party <script> tag that bypassed that pipeline entirely.

How Scanverra Detects This

Scanverra's performance check runs a real Lighthouse pass against your live URL and reports every render-blocking stylesheet and script it finds, along with the estimated time savings from removing or deferring each one - the same run used to score LCP, TTFB, and the rest of your performance score.

FAQ

Frequently asked questions

Is all CSS render-blocking?

By default, yes - the browser won't paint anything until it's finished downloading and parsing every stylesheet in the <head>, because it can't know what the page should look like otherwise. Media-attribute-scoped stylesheets (print, or a max-width query the current viewport doesn't match) are the exception - the browser downloads them at low priority without blocking render.

What's the difference between defer and async on a script tag?

Both let the HTML parser continue instead of stopping to fetch the script. async runs the script the instant it finishes downloading (which can be before the HTML is fully parsed, and out of order relative to other scripts); defer waits until parsing is complete and runs scripts in their original order - defer is almost always the safer default.

Does inlining all my CSS solve this?

Inlining everything removes the extra network request but adds that full weight to every HTML response and prevents the browser from caching it separately - the better pattern is inlining only the critical, above-the-fold CSS and loading the rest asynchronously.

Will this fix my LCP score too?

Often, yes - render-blocking resources delay first paint, which pushes back everything after it, including LCP. But they're tracked as separate Lighthouse audits because a page can have zero render-blocking resources and still have a slow LCP from an unoptimized hero image, or vice versa.

Free - no sign-up required

Find your render-blocking resources

Run a performance audit and see exactly which scripts and stylesheets are delaying first paint.

Run free audit