How to defer scripts in WordPress

Append the defer attribute to JavaScript files on your WordPress site in order to avoid render-blocking scripts and improve performance.


Modern websites, including those built on WordPress, use an ever-increasing number of third party scripts to power non-essential functionality such as analytics, chat widgets and media embedding.

By default, a simple script tag will be interpreted as a render-blocking file. As the browser parses the HTML markup it has received from the server, whenever it encounters a render-blocking script tag it will stop and execute the contents of that file before it continues processing the rest of the page.

Any scripts that are not essential to how the page initially renders can be made asynchronous or can be deferred until that initial render has taken place. If you’re enqueueing scripts within your functions.php or equivalent within a WordPress site, however, you will need a way to add the necessary defer or async attributes to your script tags and the following code snippet will help.

Simply place the following code into your functions.php file or equivalent and define the IDs of the script file(s) that you want to add a defer attribute to in $defer_scripts array. This same function can be modified or replicated for the async tag.

What’s the difference between async and defer?

Appending an async parameter to a script file tells the browser that this file can be downloaded without pausing the parsing of the page HTML. However, once the third party JavaScript file has finished downloading, parsing of the HTML will be paused whilst that code is executed. Since script files from different locations will finish downloading at different times, the use of async offers no guarantee about the order in which JS files will be executed. The async tag is only available for externally hosted script files.

A defer parameter, on the other hand, tells the browser that this file should only be downloaded and executed after the HTML parsing has completed. Any deferred scripts will also execute in the order that they appear in the document.

For more information and a helpful illustration of the effects of both the async and defer attributes, Growing with the Web have a concise and informative article.


/*
 * Add defer attribute to enqueued scripts
 *
 * @param string $tag
 * @param string $handle
 * @param string $src
 * @return void
 */

function defer_scripts( $tag, $handle, $src ) {

    // The handles of the enqueued scripts we want to defer
	$defer_scripts = [
        'SCRIPT_ID'
    ];

    // Find scripts in array and defer
    if ( in_array( $handle, $defer_scripts ) ) {
        return '<script type="text/javascript" src="' . $src . '" defer="defer">' . '\n';
    }
    
    return $tag;
} 

add_filter( 'script_loader_tag', 'defer_scripts', 10, 3 );

A lightweight, intuitive WordPress theme to enable flexible developement.

  • Lighting-fast installer
  • Intuitive SASS structure
  • Bloat-free

Build with Barebones