search ]

How to Defer JavaScript Execution and Improve Loading Times?

I often encounter the question of how to defer the loading of JavaScript on WordPress websites (Defer Loading of Javascript). The main reason for wanting to do this is in order to improve the speed of your site and ensure that content is displayed before scripts are loaded.

Before we continue, it should be noted that from WordPress version 6.2 and above, it is possible to set the way a script is loaded when performing enqueue. Therefor, you can choose wether the script will have either the ‘defer’ or the ‘async’ attribute during the enqueueing process.

If you search on Google, you’ll find many solutions, some of which work and some don’t. This seems to be one of the gray and less clear areas in the pursuit of improving the loading time of your WordPress site.

In this article, I’ll provide two recommended ways to defer the loading of JavaScript on your WordPress site in order to improve site speed. Of course, many caching plugins like Wp-Rocket and others allow you to do this without code intervention, so if you’re using them, you don’t need to do anything in this regard.

Why Defer JavaScript Loading?

JavaScript files are loaded on almost every page of your site. When loaded, the browser goes through the code, and each time it encounters a call to a specific script, it loads that script but delays the loading of what’s really important to visitors, which is the content.

It’s the responsibility of the site developer to ensure that the main and critical content for the visitor is loaded first, and only then additional elements and secondary scripts like share buttons, widgets, comments, etc., are loaded.

The idea is to present the visitor first with the text (which in most cases is the content that interests them) and delay the loading of scripts until after this content is loaded. If you check your site with tools like Pingdom, GTmetrix, or Google Page Speed Insights, you’ll likely receive a warning like “Defer loading of javascript” or something similar to “Remove Render-Blocking JavaScript.”

If you receive this warning, follow this article, and I’ll show you how to solve it in a simple way. Even if you don’t get this error, you’ll find some new things in the guide, so stick around… 🙂

Before we start, know that there are three options for loading scripts on a site. The answer to “which option is correct” depends on the nature of the scripts themselves. Pay attention to the following graphs; they help a lot in understanding the difference between the three options:

defer-vs-async-map

Default <script>

The browser will parse the html until it encounters a script. At that point, parsing will pause, and a call to the script will be made (downloading the script if it’s external). Then the script will run, and only after that will the browser continue parsing the html.

defer-vs-async

<script async>

The browser will download the script while parsing the html. Once the script is downloaded, parsing will pause, the script will run, and then the browser will continue parsing the html.

defer-vs-async

<script defer>

The browser will download the script while parsing the html and will run the script only after parsing is complete. The defer option ensures that scripts on your site will run in the order they appear in the document.

script-defer

How to Defer JavaScript Loading?

As always, you need to test every change you make. If you encounter an error related to a specific script, don’t apply this change to that script. So, let’s get started. There are two main ways to defer the loading of javascript on a WordPress site:

1. Defer Loading of All Scripts Except jQuery

This is the method I recommend and use. If you add the following script to your functions.php file and apply it to all JavaScript calls on your site except for the call to jquery.min.js, the defer attribute will be added:

/* defer all js except jquery.min.js */
if ( !is_admin() ) {
    function defer_parsing_of_js ( $url ) {
        if ( FALSE === strpos( $url, '.js' ) ) return $url;
        if ( strpos( $url, 'jquery.min.js' ) ) return $url;

        // return "$url' defer ";
        return "$url' defer onload='";
    }
}
if ( !is_admin() ) {
    add_filter( 'clean_url', 'defer_parsing_of_js', 11, 1 );
}

Pay attention to the jQuery file name your theme loads; sometimes it’s simply called jquery.js, so adjust the line accordingly.

The above code will ensure that all scripts are loaded only after the browser finishes parsing the html. If you check your site’s source code, you’ll notice that the word defer has been added to each script except for jquery.min.js:

Defer-JavaScript-Loading-in-WordPress-Speed
If you want to achieve asynchronous loading, change the word “defer” to “async” in line number 10.

2. Defer Loading of Scripts by Handle

With the release of WordPress version 4.1, a new filter was introduced that provides a relatively simple way to add defer or async to scripts on your WordPress site. The filter is called script_loader_tag, and it’s used by the following code:

function add_defer_attribute($tag, $handle) {
    if ( 'my-js-handle' !== $handle )
        return $tag;
    return str_replace( ' src', ' defer src', $tag );
}
add_filter('script_loader_tag', 'add_defer_attribute', 10, 2);

You need to change the handle in line 2 to match the handle used when you properly enqueue the script. For example:

wp_register_script('my-js-handle', $src, $deps, $ver, $in_footer);

If you want to achieve asynchronous loading using this method, change the word “defer” to “async” in line number 4.

What if You Want to Defer More than One Script?

To defer multiple scripts using this method, you need to create an array, loop through that array, and add defer to each script. Add the following code to your functions.php file and include your handles in line 2:

function add_defer_attribute($tag, $handle) {
   $scripts_to_defer = array('my-js-handle', 'another-handle');
   foreach($scripts_to_defer as $defer_script) {
      if ($defer_script !== $handle) return $tag;
      return str_replace(' src', ' defer src', $tag);
   }
   return $tag;
}
add_filter('script_loader_tag', 'add_defer_attribute', 10, 2);

In Summary

In this guide, we’ve explored the two recommended ways to delay the deployment of javascript on WordPress sites and explained the differences between async & defer. This simple process will significantly upgrade the speed of your WordPress site.

By the way, if you’re using YouTube videos on your site, there’s a way to delay the deployment of JavaScript for those videos and load them only after the page has loaded. Take a look at the guide on delaying JavaScript for YouTube videos.

If you have additional methods to achieve this, feel free to share with us! Either way, comments, feedback, and suggestions are warmly welcomed 🙂

0 Comments...

Leave a Comment

To add code, use the buttons below. For instance, click the PHP button to insert PHP code within the shortcode. If you notice any typos, please let us know!

Savvy WordPress Development