WP AI Agent
Features Pricing Blog Contact Download Plugin Manage Subscription Get Free Key →

How to Defer Render-Blocking JavaScript in WordPress

· · 9 min read

Learning how to defer render-blocking JavaScript in WordPress is one of the most impactful performance optimisations you can make for your website. When a browser encounters a JavaScript file in the HTML document, it stops parsing the page, downloads the script, executes it, and only then continues rendering — a process that can dramatically slow down your site's perceived load time and hurt your Core Web Vitals scores. In this comprehensive guide, you will learn exactly what render-blocking JavaScript is, why it matters, and several proven methods to fix it in WordPress.

What Is Render-Blocking JavaScript and Why Does It Matter?

When your WordPress site loads, the browser reads your HTML from top to bottom. Each time it encounters a <script> tag without a defer or async attribute, it pauses the entire rendering process to fetch and run that script. This is known as render-blocking behaviour, and it directly increases your page's Time to First Paint (TFP) and Largest Contentful Paint (LCP) — two critical Core Web Vitals metrics that Google uses as ranking signals.

How Render-Blocking Scripts Affect Performance

Consider a page that loads five external JavaScript files — jQuery, a slider library, a tracking pixel, a chat widget, and a custom theme script. Without deferring, the browser must wait for all five to download and execute before it can display anything to the user. On a slow connection, this can add several seconds to the perceived load time, causing visitors to abandon your site before it even appears.

The Difference Between defer and async

There are two HTML attributes you can add to a <script> tag to prevent render-blocking:

  • defer — The script is downloaded in parallel but executed only after the HTML has been fully parsed. Scripts with defer maintain their execution order, making it safe for scripts that depend on each other.
  • async — The script is downloaded in parallel and executed as soon as it is ready, without waiting for HTML parsing to finish. Execution order is not guaranteed, so use this only for independent scripts like analytics.

For most WordPress scripts, defer is the safer and more widely recommended choice.

How to Identify Render-Blocking JavaScript on Your WordPress Site

Before you fix the problem, you need to identify exactly which scripts are causing it. Several free tools can pinpoint the offenders quickly.

Using Google PageSpeed Insights

  1. Open pagespeed.web.dev in your browser.
  2. Enter your WordPress site URL and click Analyse.
  3. Scroll down to the Opportunities section.
  4. Look for the item labelled "Eliminate render-blocking resources".
  5. Expand it to see a list of all JavaScript and CSS files causing the issue, along with their estimated savings in milliseconds.

Using Chrome DevTools

  1. Open your WordPress site in Google Chrome.
  2. Press F12 (or Cmd+Option+I on Mac) to open DevTools.
  3. Click the Performance tab and press the record button, then reload the page.
  4. Stop the recording and look at the waterfall chart for long yellow blocks — these represent JavaScript parsing and execution on the main thread.
  5. Hover over each block to see the script name and its impact.

Method 1 — Using a WordPress Performance Plugin

The easiest and most beginner-friendly way to defer render-blocking JavaScript in WordPress is through a dedicated performance or caching plugin. These tools handle the heavy lifting without requiring you to write any code.

Using WP Rocket (Premium)

WP Rocket is the most popular premium performance plugin and offers the most straightforward deferral options.

  1. Purchase and install WP Rocket from wp-rocket.me.
  2. Activate the plugin and navigate to Settings > WP Rocket in your WordPress dashboard.
  3. Click the File Optimisation tab.
  4. Scroll to the JavaScript Files section.
  5. Check the box next to "Load JavaScript deferred".
  6. Optionally, check "Safe Mode for jQuery" if your theme or plugins rely heavily on jQuery.
  7. Scroll to the bottom and click Save Changes.
  8. Clear your cache by clicking Clear Cache at the top of the page.

Using LiteSpeed Cache (Free)

  1. Install and activate the LiteSpeed Cache plugin from the WordPress plugin repository.
  2. Go to LiteSpeed Cache > Page Optimisation in your dashboard.
  3. Click the JS Settings tab.
  4. Enable JS Defer and optionally JS Delay for further optimisation.
  5. Click Save and then purge your cache.

Using W3 Total Cache (Free)

  1. Install and activate W3 Total Cache.
  2. Navigate to Performance > Minify.
  3. Under the JS section, set the method to Manual and enable Embed Type: Non-blocking (defer).
  4. Save your settings and flush all caches.

Method 2 — Adding defer via functions.php (Code Method)

If you prefer a lightweight, plugin-free approach, you can add the defer attribute to your scripts directly in your theme's functions.php file. This method gives you full control over which scripts are deferred.

Filtering Script Tags with wp_script_attributes

WordPress 6.3 and later introduced the wp_script_attributes filter, which is the cleanest modern approach. Add the following snippet to your child theme's functions.php file:

/**
 * Defer render-blocking scripts in WordPress.
 * Excludes admin pages and the jQuery core script.
 */
function wptutor_defer_scripts( $tag, $handle, $src ) {
    // Do not defer scripts in the admin area
    if ( is_admin() ) {
        return $tag;
    }
    // List of script handles to exclude from deferral
    $exclude = array( 'jquery-core', 'jquery-migrate' );
    if ( in_array( $handle, $exclude, true ) ) {
        return $tag;
    }
    // Add defer attribute if not already present
    if ( false === strpos( $tag, ' defer' ) ) {
        $tag = str_replace( ' src=', ' defer src=', $tag );
    }
    return $tag;
}
add_filter( 'script_loader_tag', 'wptutor_defer_scripts', 10, 3 );

Important: Always use a child theme so that your customisations are not overwritten when the parent theme updates. If you are using a block theme or a theme that does not use functions.php, you can place this code in a custom plugin instead.

Deferring Only Specific Scripts

To defer only a specific script by its registered handle — for example, a slider script registered as my-slider — you can target it precisely:

function wptutor_defer_specific_script( $tag, $handle, $src ) {
    $defer_handles = array( 'my-slider', 'my-chat-widget', 'my-tracking-script' );
    if ( in_array( $handle, $defer_handles, true ) ) {
        $tag = str_replace( ' src=', ' defer src=', $tag );
    }
    return $tag;
}
add_filter( 'script_loader_tag', 'wptutor_defer_specific_script', 10, 3 );

Method 3 — Using WP-CLI to Audit and Manage Scripts

If you manage multiple WordPress sites or prefer working from the command line, WP-CLI offers useful commands to inspect and manage registered scripts. While WP-CLI does not directly add the defer attribute, it can help you identify plugin-registered script handles so you can target them in your functions.php code.

Listing All Registered Scripts via WP-CLI

  1. SSH into your server or open your local terminal.
  2. Navigate to your WordPress installation root directory.
  3. Run the following WP-CLI command to evaluate all registered scripts:
wp eval 'global $wp_scripts; foreach( $wp_scripts->registered as $handle => $script ) { echo $handle . " => " . $script->src . "\n"; }'

This command outputs every script handle and its source URL, giving you a complete list of candidates to defer. Copy the handles of scripts that are not critical for initial page render and add them to your exclusion or inclusion arrays in the functions.php snippet above.

Activating a Performance Plugin via WP-CLI

You can also install and activate a caching plugin directly from the command line, which is especially useful for managing multiple sites:

wp plugin install litespeed-cache --activate

Testing and Validating Your Changes

After implementing any of the methods above, it is essential to thoroughly test your site to ensure that the deferral has not broken any functionality.

Re-running PageSpeed Insights

  1. Clear all caches — your plugin cache, server-level cache, and CDN cache if applicable.
  2. Open an incognito browser window to avoid cached results.
  3. Re-run your URL through Google PageSpeed Insights.
  4. Check that the "Eliminate render-blocking resources" opportunity is gone or significantly reduced.
  5. Verify that your Performance Score, LCP, and Total Blocking Time (TBT) have improved.

Manual Browser Testing

  1. Visit every important page type on your site: homepage, blog post, product page, contact page.
  2. Test interactive elements such as dropdown menus, sliders, contact forms, shopping cart functionality, and modal pop-ups.
  3. Check the browser console (F12 > Console tab) for any JavaScript errors that may have been introduced by the deferral.
  4. If you see errors, add the offending script handle to your exclusion list and re-test.

Common Issues and How to Fix Them

  • Broken dropdown menus: Usually caused by deferring jQuery or a navigation script. Add jquery-core to your exclusion list.
  • Slider not initialising: The slider's init script may be running before the DOM is ready. Exclude the specific slider handle or switch the slider plugin to one that supports deferred loading.
  • WooCommerce cart not updating: WooCommerce scripts like wc-cart-fragments can be deferred safely, but woocommerce and wc-add-to-cart should be excluded if you experience issues.

Frequently Asked Questions

Will deferring JavaScript break my WordPress site?

It can, if applied indiscriminately. Scripts that manipulate the DOM during page load — particularly those that rely on jQuery being available immediately — may malfunction if deferred. Always test thoroughly after making changes and use an exclusion list for critical scripts like jQuery core.

Should I use defer or async for WordPress scripts?

For most WordPress scripts, defer is the safer choice because it preserves execution order. Use async only for fully independent, standalone scripts such as Google Analytics or other tracking pixels that do not interact with other scripts on the page.

Does deferring JavaScript improve my Google rankings?

Yes, indirectly. Deferring render-blocking JavaScript improves Core Web Vitals metrics like Largest Contentful Paint (LCP) and Total Blocking Time (TBT). Google uses Core Web Vitals as a ranking signal as part of its Page Experience update, so faster, more responsive pages can positively influence your search rankings.

Do I need a plugin to defer JavaScript in WordPress?

No. You can defer JavaScript without any plugin by using the script_loader_tag filter in your child theme's functions.php file, as shown in the code examples in this guide. However, a plugin like WP Rocket or LiteSpeed Cache offers a more user-friendly interface and additional optimisation features that make it worth considering.

Deferring render-blocking JavaScript is a high-impact, well-established optimisation technique that every WordPress site owner should implement. Whether you choose a plugin or a code-based approach, the result is a faster, smoother experience for your visitors and a stronger signal to search engines. If managing performance settings, writing custom PHP, or running WP-CLI commands feels overwhelming, consider using WP AI Agent — a natural-language AI chat tool that lets you handle complex WordPress tasks like this simply by describing what you need in plain English, no technical expertise required.

Ready to manage WordPress with AI?

Get 100,000 tokens free every month. No credit card required.

Get Your Free License Key →

More from the blog