To eliminate render-blocking resources in WordPress, you inline critical CSS, defer or delay JavaScript, and stop plugins loading files on pages that don't need them. "Eliminate render-blocking resources" is the single most common warning in a PageSpeed Insights report on a WordPress site. It shows up because WordPress themes and plugins default to loading their CSS and JavaScript synchronously in the `<head>`, which forces the browser to download and process those files before it can render anything at all - including your LCP element.
This guide is a WordPress-specific playbook for that warning: what the theme and plugin patterns behind it actually look like, how to find the specific files blocking your site, and the ordered set of fixes that work without breaking layout or interactivity. For the general definition of the concept, see the render-blocking resources glossary entry.
TL;DR
The PSI warning "eliminate render-blocking resources" on WordPress usually points to three culprits: the theme's main stylesheet, plugin CSS files enqueued in the head, and synchronous JavaScript loaded by plugins or a page builder. Fix in this order: generate critical CSS and load the rest asynchronously (WP Rocket, LiteSpeed Cache, and FlyingPress automate this), add defer to non-essential JavaScript, delay analytics and chat widgets until interaction, conditionally dequeue plugin assets on pages that do not need them, and handle jQuery dependencies carefully so you do not break the site. Always test on staging first, keep a per-page exclude list, and run visual regression before pushing to production.
Key Takeaways
- In WordPress, the render-blocking warning almost always points to the theme stylesheet, plugin CSS/JS enqueued in the head, and jQuery-based scripts loaded synchronously.
- Critical CSS (inline the above-the-fold styles, async-load the rest) is the highest-ROI fix and is automated by WP Rocket, LiteSpeed Cache, and FlyingPress.
- Adding `defer` to JavaScript is safe for most non-jQuery scripts. Delaying scripts until user interaction is safer still for analytics, chat, and tag manager.
- Conditionally dequeueing plugin assets on pages that do not need them (Perfmatters, Asset CleanUp) often removes 4-8 render-blocking files at once.
- jQuery dependencies are the most common thing to break. Any script that expects jQuery to be loaded first cannot be deferred without adding it to an exclude list.
- Never optimize on production without a staging test and a visual regression pass. A broken menu or missing checkout button costs more than a slow page.
What Render-Blocking Resources Mean in WordPress Terms
PageSpeed Insights flags a resource as render-blocking when it is a stylesheet or a synchronous script in the `<head>` that the browser has to download and process before it can render the first pixel. On WordPress, that almost always means one of the following.
The theme's main stylesheet (typically `style.css` or a bundled `main.css`). It is enqueued in the head with `wp_enqueue_style` and loads synchronously. On a well-built theme it is 20-60 KB. On a multipurpose theme with a page builder it is 200-500 KB.
Plugin CSS files enqueued site-wide. Every plugin that has front-end UI (contact forms, sliders, reviews, WooCommerce extensions, cookie banners) typically loads its own stylesheet in the head on every page, whether the plugin runs on that page or not. Ten active plugins routinely means ten additional render-blocking CSS files.
Synchronous JavaScript. jQuery, jQuery Migrate, jQuery UI, and plugin JavaScript that a developer forgot to defer. Even a small 5 KB script blocks HTML parsing if it is loaded synchronously in the head.
Google Fonts loaded via a blocking `<link>` in the head. The stylesheet request from `fonts.googleapis.com` blocks rendering, and then the actual font files block text painting.
Eliminating render-blocking on WordPress is really about fixing these four patterns.
Old and New Names for the Render-Blocking Warning
The same problem has gone by several names, which is why advice online can look contradictory.
Eliminate Render-Blocking JavaScript and CSS in Above-the-Fold Content
This was the wording in older versions of PageSpeed Insights. It describes exactly the same issue as today's warning: CSS and synchronous JavaScript in the head that the browser must process before it can paint the visible part of the page. The WordPress fixes in this guide apply unchanged.
Render-Blocking Requests (the New Lighthouse Wording)
Recent Lighthouse and PageSpeed Insights versions group this under an insight called render-blocking requests. To fix render-blocking requests in WordPress, follow the same steps below: critical CSS, deferred and delayed JavaScript, and conditional asset loading. The list of flagged files and their estimated savings is the same information, presented as an insight.
Defer Parsing of JavaScript
GTmetrix and older tools called the JavaScript half of the problem "defer parsing of JavaScript." It means the same thing as deferring render-blocking JavaScript, covered in step 2.
How to Fix Render-Blocking Resources: Find the Culprits
The fix starts with a list, not a plugin setting. Before changing anything, identify the specific files blocking your specific site. Guessing wastes time and often breaks something unrelated.
PageSpeed Insights. Run PSI on a representative page (usually your homepage and one product or post). The Opportunities section will list "Eliminate render-blocking resources" with each specific file, its transfer size, and the estimated LCP savings from removing it. This is your target list.
Chrome DevTools Coverage tab. Open DevTools, press Ctrl+Shift+P, type "Show Coverage", and reload the page. Coverage shows every CSS and JS file loaded and what percent of each is actually used. A stylesheet with 92% unused bytes on the homepage is almost certainly being loaded by a plugin that has no reason to run there.
Our free render-blocking finder. The render-blocking finder tool crawls a URL and lists every render-blocking resource with its size and origin, without needing to open DevTools.
The output of this step is a list of specific files you are going to unblock, defer, delay, or dequeue. Do not skip it.
1. Critical CSS in WordPress: Remove Render-Blocking CSS
To remove render-blocking CSS, inline the critical CSS and load the full stylesheet asynchronously. The biggest single win is separating the CSS the browser needs to render the above-the-fold view from the rest of the stylesheet. Extract the critical (above-the-fold) rules, inline them in the `<head>`, and load the full stylesheet asynchronously so it does not block rendering.
<style>/* inlined critical CSS: 8-20 KB */</style>
<link rel="preload" as="style" href="/style.css" onload="this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="/style.css"></noscript>
Doing this by hand for a WordPress site is painful because every template needs a different critical CSS payload. Use a caching plugin that automates it.
WP Rocket ships a "Remove Unused CSS" feature that generates per-template critical CSS on the fly and async-loads the rest.
LiteSpeed Cache ships "CCSS" (Critical CSS) as part of its optimization suite, tied to its QUIC.cloud service.
FlyingPress ships "Generate Critical CSS" and "Lazy Render HTML" that together do the same job with less configuration.
See the comparison in best WordPress speed plugins for which one fits your stack. Whichever plugin you use, always test on staging first because plugin-generated critical CSS occasionally misses styles used in menus, modals, or accordions and causes a flash of unstyled content.
2. Defer Parsing of JavaScript in WordPress
To defer parsing of JavaScript, add the `defer` attribute to scripts that don't need to run before first paint. The `defer` attribute tells the browser to download the script in parallel with HTML parsing but only run it after parsing is done. This removes the script from the render-blocking path without changing its execution order relative to other deferred scripts.
<script src="/plugin.js" defer></script>
Defer is safe for almost every script except those that expect jQuery to be already defined when they run (see the jQuery section below).
How to defer in WordPress. WP Rocket, LiteSpeed Cache, and FlyingPress all have a "Load JavaScript deferred" toggle that adds `defer` to every enqueued script. If you are not using a plugin, add a `script_loader_tag` filter in your theme's functions.php that adds `defer` to matching handles.
Defer parsing of JavaScript with WP Rocket. In WP Rocket, open File Optimization and turn on "Load JavaScript deferred." Add any script that breaks to the exclusion box (jQuery is the usual one), then retest.
Defer JavaScript in WordPress without a plugin. Since WordPress 6.3 you can pass a loading strategy when you enqueue a script, which is the cleanest manual method:
wp_enqueue_script( 'my-slider', get_template_directory_uri() . '/js/slider.js', array(), '1.0', array( 'strategy' => 'defer', 'in_footer' => true ) );
For scripts enqueued by plugins, use the `script_loader_tag` filter instead and match on the script handle.
Do not use `async` for anything except analytics. `async` runs the script as soon as it downloads, in whatever order they arrive, which frequently breaks anything that depends on load order (jQuery plugins, framework components).
3. Delay JavaScript Until Interaction
Analytics, tag manager, chat widgets, heatmaps, and marketing pixels never need to run before the user interacts with the page. Delaying them until the first scroll, mouse move, or touch removes them from the initial LCP window entirely and dramatically improves both LCP and INP. This matters because the median page now ships 375 KB of third-party JavaScript, roughly two-thirds of all JS on a typical WordPress site, and almost none of it is needed for first paint.
This is different from `defer`. Deferred scripts still run after HTML parsing completes; delayed scripts do not run until the user does something.
WP Rocket ships "Delay JavaScript Execution" with a default exclude list.
FlyingPress ships "Delay JavaScript" with per-script granularity.
Perfmatters ships "Delay JavaScript" with a pattern-matching UI.
Do not delay JavaScript that your first paint depends on (theme framework runtime, cookie consent banners in some regions, above-the-fold sliders). The delay lists in the plugins above ship with sensible defaults; extend them cautiously.
4. Conditionally Load Plugin Assets (Including Elementor)
The cleanest fix for a plugin CSS or JS file that loads on every page but is only used on one is to stop loading it on the pages that do not need it. WordPress core does not support this out of the box, but two plugins do.
Perfmatters ships a script manager with a UI that lets you disable each plugin's scripts on a per-page, per-post-type, per-URL-pattern, or site-wide basis.
Asset CleanUp does the same job with a slightly different UI. It also detects and lets you disable unused CSS and JS on each page individually.
Typical wins: disable the contact form plugin on every URL except the contact page, disable the WooCommerce cart fragments script on non-shop pages, disable page builder CSS on posts and pages not built with the builder. Each dequeue removes one render-blocking resource from the page's list.
Always verify on staging. It is easy to accidentally dequeue an asset that a header or footer widget depends on.
Elementor Render-Blocking Resources
Elementor sites tend to show a long render-blocking list because the builder, its add-ons, icon libraries, and Google Fonts all load in the head. Start inside Elementor: its Features and Performance settings include options to load only the CSS and scripts the widgets on each page actually use, and to stop loading Font Awesome and Google Fonts you don't need. Then apply critical CSS and JavaScript delay through your caching plugin, and test sliders, popups, and motion effects, which are the elements most likely to break.
5. Handle jQuery Dependencies Safely
jQuery is the most common thing to break when eliminating render-blocking resources. WordPress core loads jQuery in the head by default, and hundreds of plugins and themes assume it is present and defined before their own inline scripts run.
What breaks. If you defer jQuery, any inline script that runs `jQuery(function($){ ... })` before the deferred jQuery has loaded will throw "jQuery is not defined" and stop executing. Menus, sliders, tabs, and form validation are common victims.
Safe options.
Leave jQuery undeferred but defer everything else. Most speed plugins' "defer JavaScript" toggles ship with jQuery on the exclude list for this exact reason.
Move jQuery to the footer. Setting `wp_scripts()->add_data('jquery', 'group', 1)` moves it out of the render-blocking path in the head. Works only if no theme or plugin inline scripts in the head expect jQuery to exist.
Audit and remove jQuery dependency where possible. Modern themes (GeneratePress, Blocksy, Kadence, Bricks) do not require jQuery in the front-end. If your theme is one of these, you can dequeue jQuery entirely on pages where no plugin needs it.
When in doubt, exclude jQuery from defer, ship the rest of the optimizations, and revisit jQuery once everything else is stable.
6. Google Fonts Render Blocking: Preload and font-display: swap
Google Fonts are render blocking when they load through a stylesheet link in the head, and self-hosting them with `font-display: swap` fixes it. Web fonts themselves are technically not "render-blocking resources" in the PSI sense (they do not block first paint) but they are text-render-blocking, which delays LCP when the LCP element is a heading.
Add `font-display: swap` to every @font-face rule so the browser paints text immediately in a fallback and swaps in the webfont when it arrives.
Preload the font file used above the fold.
<link rel="preload" as="font" type="font/woff2" href="/fonts/inter.woff2" crossorigin>
Self-host Google Fonts instead of loading from `fonts.googleapis.com`. Self-hosting removes an extra DNS lookup and TCP connection (typically 100-300 ms) and lets you preload the font file directly. WP Rocket, LiteSpeed Cache, and OMGF (Optimize My Google Fonts) all automate the self-hosting step.
For the extraction concept underlying critical CSS, see the critical CSS glossary entry.
Plugin or No Plugin: Choosing Your Approach
Most sites should eliminate render-blocking resources in WordPress with a plugin, and only go manual for the files a plugin can't handle cleanly.
Plugins That Eliminate Render-Blocking Resources
A caching plugin covers the bulk of the work: WP Rocket, LiteSpeed Cache, and FlyingPress each handle critical CSS, deferred JavaScript, and delayed JavaScript. Add Perfmatters or Asset CleanUp when you need per-page control over which plugin files load. Use one tool per job; two plugins both rewriting CSS or JavaScript is the most common cause of a broken layout.
Eliminating Render-Blocking Resources Without a Plugin
The manual route is realistic for developers on a custom or lean theme: enqueue scripts with the `defer` strategy, dequeue plugin assets with `wp_dequeue_script` and `wp_dequeue_style` on pages that don't use them, self-host fonts, and generate critical CSS with a build tool. It gives you full control and no plugin overhead, but every new plugin or template means revisiting the setup by hand.
If you'd rather not do either, our WordPress speed optimization service clears the render-blocking warning as part of a guaranteed Core Web Vitals pass.
Test-Safely Checklist
Every one of these fixes can break something visible. Follow this before you ship any change to production.
Always test on staging first. Never enable critical CSS, defer JavaScript, delay JavaScript, or dequeue plugin assets on a live site without a staging copy to test on.
Keep a per-page exclude list. Critical CSS occasionally misses styles used in menus, modals, or accordions. Every speed plugin lets you exclude URLs from optimization; use it for pages where the automated fix produces a visible issue.
Visual regression before pushing. Open the homepage, one product page, one blog post, the cart, the checkout, and the contact page in incognito with the optimizations on. Look at every above-the-fold section for missing background images, unstyled text, or shifted layout. Interact with every menu, modal, filter, and form.
Watch INP and LCP in field data. A defer or delay change occasionally makes INP worse (because a script now runs later, right when the user tries to interact). Watch the 75th-percentile numbers for a week after shipping.
Keep a rollback plan. Every optimization plugin above has an "exclude URL" or "disable optimization" button. Know how to hit it fast if something breaks on the live site.
Frequently Asked Questions
What are render-blocking resources in WordPress?
In WordPress, render-blocking resources are almost always the theme's main stylesheet, plugin CSS files enqueued in the head, synchronous JavaScript (often jQuery and jQuery-dependent plugin scripts), and Google Fonts loaded via a blocking link tag. Any of these that sits in the head without defer or async prevents the browser from rendering the first pixel until they finish downloading and parsing.
Does WP Rocket eliminate render-blocking resources?
Yes. WP Rocket ships "Remove Unused CSS" (generates per-template critical CSS and async-loads the full stylesheet), "Load JavaScript deferred" (adds defer to enqueued scripts), and "Delay JavaScript execution" (delays non-essential scripts until user interaction). Together these address the three main render-blocking causes in a typical WordPress install. LiteSpeed Cache and FlyingPress ship equivalent features.
What does render-blocking mean?
Render-blocking means the browser has to stop and finish downloading and processing a file before it can show anything on screen. CSS in the head and scripts without `defer` or `async` are render-blocking by default, which is why they delay First Contentful Paint and Largest Contentful Paint.
What are render-blocking scripts?
Render-blocking scripts are JavaScript files loaded in the head without `defer` or `async`. When the browser's parser reaches one, it pauses building the page until the script downloads and runs. In WordPress these are usually jQuery, page builder scripts, and plugin scripts enqueued in the header.
Why does render-blocking show up more on mobile?
PageSpeed Insights tests mobile on a throttled connection and a slower simulated CPU, so the same render-blocking files cost more time and get flagged with bigger savings. To eliminate render-blocking resources on mobile, apply the same fixes; mobile scores usually improve the most.
Can removing render-blocking resources break my site?
Yes, and it commonly does on the first attempt. Critical CSS occasionally misses styles used in menus, modals, or accordions and causes a flash of unstyled content. Deferring jQuery breaks any inline script that assumes jQuery is already defined. Delaying JavaScript breaks widgets that need to run before user interaction. Always test on staging first, keep a per-page exclude list, and run visual regression on your most important templates (homepage, product, checkout) before pushing to production.
Do I still need this on a fast theme?
Somewhat less, but usually still yes. A fast theme like GeneratePress or Blocksy ships far less CSS and JavaScript than a multipurpose theme, so the theme's own contribution to render-blocking is minor. But the plugins you install on top still enqueue their own CSS and JS on every page. Even on a lean theme, conditionally dequeueing plugin assets and delaying analytics or tag manager typically shaves 200-600 ms off LCP.