Defer jQuery in WordPress

Learn how to defer jQuery in WordPress for extra pagespeed

Arjen Karel Core Web Vitals Consultant
Arjen Karel
linkedin

A guide to deferring jQuery in WordPress

Greetings, fellow performance aficionados! I'm excited to share insights on optimizing your WordPress site and improving the Core Web Vitals. Today I will show you how to defer the loading of jQuery, enhancing your website's speed and, consequently, the user experience.

Why Defer jQuery?

jQuery, a robust JavaScript library, is undoubtedly a powerful tool, but its synchronous loading can sometimes slow down the initial page load. Many themes that are available  on the various marketplaces rely on jQuery. Not jQuery is built to be deferred but unfortunately many themes do not defer jQuery. 

So what is the main advantage of deferring jQuery you might ask? Well take a look at this image below. It shows the difference in HTML parsing between normal, deferred and async scripts. If jQuery if not deferred the browser will block HTML parsing until the script has been executed. If jQuery is deferred the browser will not have to block the parser. And this will save you a whole lot of time, especially when it comes to the Largest Contentful Paint

defer vs async vs sync script timelines

The reason that theme builds are not deferring jQuery by default is because of legacy. Some plugins add (inline) scripts that depend on jQuery. If jQuery is loading deferred but the script that needs jQuery is not deferred there will be a conflict (and an error)

Method 1: Manually Defer jQuery

To manually defer jQuery we need to find the 'handle' that has been used to enqueue jQuery. Next we remove it from the queue and add our own deferred version of the same file without breaking the ability to upgrade the theme file.

Step 1: Identifying jQuery Inclusion in Your Theme

To kick off the optimization process, we need to pinpoint where jQuery is included in your WordPress theme. Commonly found in the theme's functions.php file or directly in the header.php file, look for lines resembling:

wp_enqueue_script('jquery');    

We now know that the handle for jQuery is called 'jquery'. Understanding where jQuery is enqueued lays the groundwork for our optimization journey.

Step 2: Crafting a Child Theme for Long-Term Stability

Before making any changes, consider creating a child theme to safeguard your modifications against future updates. This ensures that your hard work won't be overwritten when the parent theme receives an update. Crafting a child theme is a bit like adding an extra layer of armor to your site's structure.

Step 3: Enqueue jQuery with the 'defer' attribute

Now, let's dive into the technical details. In your child theme's functions.php file add the following code and modify it to match your jQeury file location and handle. We are doing to be using the new defer strategy

function defer_jquery() {
  if (!is_admin()) {
    wp_deregister_script('jquery');
    wp_register_script('jquery', '/js/jquery/jquery.js', [], null, [ 'strategy'  => 'defer']);
    wp_enqueue_script('jquery');
  }
}
add_action('wp_enqueue_scripts', 'defer_jquery',100);

Let's break it down:

  • wp_deregister_script('jquery'): Unregisters the default jQuery script.
  • wp_register_script('jquery', '/js/jquery/jquery.js', [], null, [ 'strategy'  => 'defer']);
    : Registers jQuery with the 'defer' strategy.
  • wp_enqueue_script('jquery'): Enqueues the modified jQuery script.

Et voila: you have now successfully deferred jQuery on your WordPress site. And as a bonus you now know how to defer any script because the process is exactly the same!

Method 2: use a plugin

Plugins like WP Core Web Vitals make it super easy to defer jQuery and many plugins can even handle the complications that may arise from it by also deferring dependencies and performing a few other tricks like caching jQuery events until jQuery has been executed.

wp core web vitals defer all scripts

Method 3: CloudFlare

Another super simple way to defer jQuery is to use CloudFlare's Rocket loader. Rocket loaders works by disabling all your scripts during page load and then quickly enabling them again. This tricks mimics deferring scripts but it has a few drawbacks

  • CloudFlare Rocket Loader breaks a browser feature called the preload scanner. With Rocket loader scripts are not preloaded and it might take a bit longer for your scripts to be downloaded and executed.
  • CloudFlare Rocket Loader i a pretty blunt instrument. Is does not discriminate between important, less important and nice to have scripts. It just defers everything without any consideration and leaves you with no control over script timing.

Test, Test, Test!

After implementing these changes, thoroughly test your website's functionality. Pay close attention to interactive elements, animations, and features dependent on jQuery to ensure they function seamlessly. Rigorous testing guarantees that the optimization doesn't inadvertently introduce any hiccups to your user interface.

TroublseShooting issues

If you run into any issues those will probably fall into one of 3 categories. Most issues can be found by opening the inspector and navigating to the console tab. If there are any issues you will like;ly find warnings that loo something this this and read 'Uncaught ReferenceError: jQuery is not defined'

reference error jquery not defined if deferred

Fixing them is not that hard to do. Next tot he error is a reference to the error origin. If it is (index) is most likely originates from an inline script. If it is another file it is either a timing issues or you forgot to defer that file as well.

Dependent scripts

If you are using jQuery you are bound to have scripts that depend on jQuery. Those scripts need to be deferred as well (if the scrip that relies on jQuery is not deferred it will execute before jQuery!). Just repeat the same steps that you took to defer jQuery. Fortunately you have already laid the groundwork so this should be a walk in the park!

Inline Scripts

Inline scripts are a problem if they rely on jQuery! Normal inline scripts cannot be deferred.  If you add the defer attribute it will just be ignored by browsers. There are 2 ways to fix issues from inline scripts
$(function(){
 // do something
})
  • Use the type="module" trick. The newer <script type="module"> will also defer inline JavaScript.
  • Place inline scripts in an external file. If you need variables you can add those in an inline script directly on the page but the main jQuery dependent functions should be in an external file that is also deferred. 

Timing issues

Another, less common issue originates from timing. If jQuery is not deferred it will execute before the  DOMContentLoaded and load event. You can depend on this. If is is deferred a script might be executed after the DOMContentLoaded event. This means if you have attached an event handler on the DOMContentLoaded event, it will not reliably be executed. If you run into issues like these try changing the trigger or wrapping the function into jQuery()

And as always, if you are stuck don't hesitate to hire me for a 2 hour session!

I help teams pass the Core Web Vitals:

lighthouse 100 score

A slow website is likely to miss out on conversions and revenue. Nearly half of internet searchers don't wait three seconds for a page to load before going to another site. Ask yourself: "Is my site fast enough to convert visitors into customers?"

Defer jQuery in WordPressCore Web Vitals Defer jQuery in WordPress