🎉 Free WordPress fix for our first 50 sites — in exchange for an honest review. Claim a spot →

Performance

Fix Render-Blocking Resources in WordPress: A Real Guide

Jul 7, 2026 · 7 min read · By the Mend engineering team

Render-blocking CSS and JavaScript are files that force a visitor's browser to pause and download them before it can draw a single pixel of your page. Eliminating or deferring them is one of the highest-impact performance wins available in WordPress — and it is entirely fixable without touching a line of server config. This guide walks you through exactly what is happening, why it happens on WordPress sites specifically, and the concrete steps to resolve it.

What "Render-Blocking" Actually Means

When a browser loads a web page it parses HTML top to bottom. The moment it encounters a <link rel="stylesheet"> or a <script> tag in the <head>, it stops parsing and goes to fetch that file. Until the file is downloaded, parsed, and (for scripts) executed, the browser cannot render anything the visitor sees. That pause is what PageSpeed Insights and Core Web Vitals tooling label as render-blocking.

The direct consequence is a higher Largest Contentful Paint (LCP) and a worse First Contentful Paint (FCP) — two of Google's Core Web Vitals. A page that feels instant on a fast laptop can feel broken on a mid-range mobile device on a 4G connection, which is exactly the scenario Google's scoring simulates.

Why WordPress Sites Are Especially Prone to This

WordPress is not uniquely bad — but its architecture makes the problem common:

  • Plugins enqueue their own assets unconditionally. A contact form plugin loads its stylesheet and script on every page, even pages without a form. A slider plugin does the same. Each one is a potential render-blocker.
  • Themes import Google Fonts inline in <head>. A Google Fonts <link> in the head is render-blocking. Many themes have done this by default for years.
  • jQuery and its dependents load synchronously. WordPress core loads jQuery in the head by default. Dozens of plugins depend on it and load their own scripts immediately after, chaining the block.
  • Page builders add asset pipelines of their own. Elementor, Divi, WPBakery, and similar builders each ship CSS and JavaScript frameworks that may load before the browser can paint anything.

How to Identify Which Files Are the Problem

Before touching anything, find the actual offenders.

  1. Open PageSpeed Insights and run your URL. Scroll to the "Eliminate render-blocking resources" opportunity. It lists every file by URL.
  2. In Chrome DevTools, open the Performance tab, record a page load, and look at the waterfall. Gray bars at the very start — before any paint — are your blockers.
  3. The Coverage tab (Cmd+Shift+P → "Show Coverage") shows what percentage of each CSS file is actually used on the current page. Files that are 80 %+ unused are prime candidates for deferral or removal.

Write down the file URLs. Most will contain a plugin or theme slug, which tells you exactly where to act.

The Fix Hierarchy: Easiest to Most Involved

Step 1 — Remove assets you do not need

The fastest fix is dequeuing a stylesheet or script that should not load at all. If a plugin loads a stylesheet on every page but only needs it on one, that is a bug in the plugin. You can work around it by adding a snippet to your theme's functions.php or, better, a code-snippets plugin:

add_action( 'wp_enqueue_scripts', function() {
    if ( ! is_page( 'contact' ) ) {
        wp_dequeue_style( 'my-plugin-style-handle' );
        wp_dequeue_script( 'my-plugin-script-handle' );
    }
}, 100 );

The handle names come from the plugin's own wp_enqueue_style() or wp_enqueue_script() calls — inspect the plugin's source or use the free Query Monitor plugin, which lists every enqueued handle and where it was registered.

Step 2 — Defer or async non-critical JavaScript

Scripts that do not need to run before the page paints should load with defer or async. The difference matters:

  • defer — downloaded in parallel, executed in order after HTML is parsed. Safe for most scripts that depend on the DOM or on each other.
  • async — downloaded in parallel, executed immediately when ready, in any order. Safe only for fully independent scripts (analytics, chat widgets).

In WordPress you can add defer via a filter:

add_filter( 'script_loader_tag', function( $tag, $handle, $src ) {
    $defer = [ 'my-plugin-script', 'another-handle' ];
    if ( in_array( $handle, $defer, true ) ) {
        return str_replace( '<script ', '<script defer ', $tag );
    }
    return $tag;
}, 10, 3 );

Do not defer jQuery itself unless you are certain every script that depends on it is also deferred and loaded after it. Deferring jQuery while leaving a dependent script synchronous causes JavaScript errors.

Step 3 — Move scripts to the footer

The second argument to wp_enqueue_script() accepts a boolean for footer loading. Scripts registered with true load before </body> rather than in <head> — a quick win for anything non-critical. You cannot change this for third-party plugins without the filter approach above, but you can for your own theme scripts.

Step 4 — Fix render-blocking CSS

CSS is harder than JavaScript because the browser genuinely needs styles to paint correctly. The right approach depends on how much of the stylesheet is used above the fold:

  • Critical CSS inlining. Extract the styles needed to render the visible viewport and inline them in <head>. Load the full stylesheet with a preload trick: <link rel="preload" as="style">. Tools like Critical or the paid tier of NitroPack automate this. It is the most effective technique but also the most complex to implement correctly.
  • Preload high-priority stylesheets. Add <link rel="preload"> for your main theme stylesheet. This does not remove the block but starts the download sooner, reducing the wait time.
  • Swap Google Fonts to self-hosted. A Google Fonts @import or <link> in <head> causes a cross-origin DNS lookup, TCP handshake, and download before the browser can continue. The OMGF (Optimize My Google Fonts) plugin downloads fonts to your server and rewrites the enqueue so the fonts load from your own domain with proper caching headers.

Step 5 — Use a caching or optimisation plugin — carefully

Plugins like WP Rocket, LiteSpeed Cache (for LiteSpeed/OpenLiteSpeed hosts), and Perfmatters expose checkboxes for defer JS, delay JS, and CSS optimisation. They work well for the majority of sites, but "Delay JavaScript Execution" — which defers all scripts until user interaction — can silently break functionality. Always test on a staging copy first. See our guide on how to set up a WordPress staging site and use it right.

Enable one feature at a time. Test. Move to the next. Enabling everything at once makes it impossible to identify what broke something.

Common Mistakes That Make Things Worse

  • Deferring scripts that write to the DOM synchronously. Some inline scripts expect a library to already be present. Deferring the library breaks them silently.
  • Relying on PageSpeed score alone. A score is a proxy, not the goal. Measure real user experience with Chrome UX Report data or field data from Search Console's Core Web Vitals report.
  • Combining everything into one giant CSS file. Concatenation reduces HTTP requests but if that one file is large, it can be a bigger render-block than the original individual files.
  • Forgetting logged-in admin users bypass caching. Always test performance in an incognito window or a different browser to see what anonymous visitors experience.

How to Prevent Render-Blocking Creep

Performance regressions are almost always caused by installing a new plugin or theme update without checking the asset footprint. Build a lightweight habit: after any significant update or new install, re-run PageSpeed Insights and compare. If the render-blocking count goes up, you know exactly which change to investigate. The pre-update checklist is a good framework to follow before any change.

If your host supports it, enabling HTTP/2 or HTTP/3 reduces the cost of multiple small requests and makes some of the concatenation and deferral complexity less urgent — though it does not eliminate render-blocking, it reduces its impact.

When to Call a Professional

If you have worked through the steps above and your LCP is still failing, or if a deferral fix broke part of your site and you cannot pinpoint which script is the culprit, the diagnostic work can become genuinely time-consuming. At that point the problem usually involves one of: a page-builder asset pipeline that requires custom configuration, a poorly coded plugin that cannot be safely deferred, or a theme architecture that needs refactoring.

That is exactly what Mend's Speed Pass is built for — a senior engineer audits your full asset load, implements safe deferral and inlining, and delivers a plain-English report of every change made, at a flat $199. If you are not sure where the problem sits, start with a free Diagnosis and get a clear answer before any work begins.


Render-blocking resources are one of the most impactful — and most fixable — performance problems in WordPress. Work through the hierarchy: remove what is not needed, defer what can wait, inline what is critical, and test every change in isolation. Most sites see meaningful LCP improvements from the first two steps alone.

Frequently asked questions

Will deferring JavaScript break my WordPress site?

It can, if a deferred script is depended upon by an inline script that runs synchronously. Always test on a staging copy first and enable deferral for one script at a time, checking site functionality after each change.

Is it safe to defer jQuery in WordPress?

Generally no, unless you also defer every script that depends on jQuery and ensure they load in the correct order. jQuery is a dependency for a large portion of WordPress plugins; deferring it carelessly causes silent JavaScript errors that break menus, forms, and sliders.

What is the difference between eliminating and deferring a render-blocking resource?

Eliminating means the file is no longer loaded at all (removed or conditionally dequeued). Deferring means the file still loads but does so in a way that does not block the browser from painting — using the defer or async attribute, or by moving it to the footer. Elimination is always better when the resource is not needed.

How many render-blocking resources is too many?

Even one large render-blocking file can significantly hurt your LCP score. The goal is zero render-blocking resources above the fold. In practice, a well-optimised WordPress site with a page builder might have two to three unavoidable ones; anything beyond that is worth investigating.