Using the HTML5 Defer Property in WordPress

I was recently busy with optimizing a website when the site report we ran over at GT Metrix mentioned that we should be deferring all scripts on the website. The HTML5 Async / Defer property was built with the idea of speeding up the loading time of website by loading all javascript files asynchronously.

Issues on using HTML5 Defer / Async in WordPress

It seemed like a good idea at the time, although I ran into several problems early on:

  • There’s quite a bit of literature on the async / defer property, but precious little on how to use within a WordPress environment;
  • Trying to implement it from coding example, led to the WordPress admin panel being broken (especially the WordPress’ Tiny MCE editor)

Literature Backtrack

Before continuing, I think it’s best to include some references to great articles on what the HTML5 defer/ async property actually does. Have a look at:

If you’re unsure of the difference between the async and defer property, it basically boils down to the order in which scripts are loaded. In both async and defer, scripts are loaded asynchronously; However, with the defer, the order is maintained. In contrast, async simply loads them as fast as it can. For WordPress, using defer is usually a better bet as it’s more than likely that there will be script dependencies… Meaning stuff will break if it’s not in right order.

Using Defer in WordPress – The Right Way

Following the work done by Emil in the article above, we set out to write some code to:

  1. Load scripts asynchronously,
  2. while keeping script dependencies intact and
  3. ensuring it works in WordPress.

To do this, we ended up doing the following:

  • We wrote a child theme for the current active parent theme (Learn how to do that over at the WordPress Codex on Child Themes)
  • We added a child theme functions.php file, and added the following code:
// Defer jQuery Parsing using the HTML5 defer property
if (!(is_admin() )) {
    function defer_parsing_of_js ( $url ) {
        if ( FALSE === strpos( $url, '.js' ) ) return $url;
        if ( strpos( $url, 'jquery.js' ) ) return $url;
        // return "$url' defer ";
        return "$url' defer onload='";
    add_filter( 'clean_url', 'defer_parsing_of_js', 11, 1 );
  • Lastly we activated the childtheme and ran the report on GT Metrix again to ensure that the deferring script worked.