All guides · Performance

Render-Blocking Resources: Get the First Paint Out Sooner

Before the browser can paint anything, it needs the HTML and every stylesheet that applies to the page. It also stops parsing the HTML whenever it meets a plain <script src> tag, downloads the script and runs it, and only then carries on. These files are called render-blocking: while they load, the visitor sees a blank screen.

Why it matters

Each render-blocking file adds at least one network round trip before the first paint. On a mobile connection that can be hundreds of milliseconds per file, and it delays both First Contentful Paint and Largest Contentful Paint. Large stylesheets make it worse: the browser must download and parse the whole file, even if the first screen uses a fraction of it.

How to fix

Defer scripts

Almost no script needs to run before the page is shown. Add defer (runs in order after the HTML is parsed) or async (runs as soon as it arrives, in any order):

<script src="/js/app.js" defer></script>
<script src="https://analytics.example.com/tag.js" async></script>

Use defer for your own scripts that depend on each other or on the DOM, and async for independent scripts such as analytics. Scripts with type="module" are deferred by default.

Inline critical CSS, load the rest later

Put the small set of rules needed for the first screen (header, hero, layout) in a <style> block in the head, and load the full stylesheet so it doesn’t block the first paint. Build tools and optimisation plugins can extract the critical rules for you. Keep the inlined part small: it is sent with every HTML response and isn’t cached on its own.

Use the media attribute

A stylesheet whose media query doesn’t match is still downloaded, but it doesn’t block rendering:

<link rel="stylesheet" href="/css/print.css" media="print" />
<link rel="stylesheet" href="/css/wide.css" media="(min-width: 1024px)" />

Splitting print or large-screen styles into their own files keeps them off the critical path.

Remove unused CSS

Themes and page builders often ship one large stylesheet for every page and every widget. The browser still has to download and parse all of it before painting. Remove rules you no longer use, split styles per template or component, and don’t load a plugin’s stylesheet on pages that don’t use the plugin.

WordPress

Since WordPress 6.3, scripts can be enqueued with a loading strategy:

wp_enqueue_script('my-theme', get_template_directory_uri() . '/js/theme.js', [], '1.2.0', [
  'strategy' => 'defer',
  'in_footer' => true,
]);

For plugin and theme assets you don’t control, optimisation plugins such as Autoptimize, WP Rocket or LiteSpeed Cache offer options to defer JavaScript, generate critical CSS and remove unused CSS. Test the site after turning these on: deferring a script that inline code depends on can break menus, sliders or forms.

Nginx, Apache and Cloudflare

Render blocking is decided by the HTML, so there is no server setting that fixes it. The server can still help by making the remaining blocking files arrive faster: enable text compression, HTTP/2 or HTTP/3, and long cache lifetimes for versioned CSS and JavaScript.

Common mistakes

  • Adding async to scripts that depend on each other, such as jQuery and its plugins. Use defer so they keep their order.
  • Loading web fonts through a CSS @import inside another stylesheet, which adds a chain of blocking requests. Use a <link> in the head instead.
  • Inlining the whole stylesheet. That moves the cost into the HTML rather than removing it.

How PerfoMetrix checks this

We read two audits from the Lighthouse report of the PageSpeed Insights run we already make (mobile, simulated device): render-blocking requests (render-blocking-insight) and unused CSS (unused-css-rules). If Lighthouse rates an audit 0.9 or higher, or it doesn’t apply to the page, the check passes; otherwise it needs attention. We show Lighthouse’s estimate, such as “Est savings of 1,200 ms”, and the first five files it lists.

These checks are shown but don’t count toward the performance score: their effect is already measured by FCP and LCP, which are scored. No extra requests are made to your site.

Learn more

Last updated October 28, 2026