Age of Article Warning:
This article was originally published 22 months ago. The tips and techniques explained may be outdated, or information may longer be applicable. Please consider this when viewing the below content.

Loading scripts and stylesheets is an integral part of the page loading for any website. These days we are well aware that web pages contain more interactivity, elements and scripts, accomplishing so much more than the early years when a website was just a simple HTML page (the very first website).

Page Loading Speed is Important

So how do we make sure that despite all the stuff that is going on while a webpage loads, the page still loads fast enough to prevent a viewer from impatiently “bouncing” away to another website. Well in WordPress we are encouraged to enqueue the scripts in the footer and load the stylesheets in the header.

The reason for this so that we want the web page’s visual elements to load first, so people see that the page is rendering. Otherwise a blank loading screen is a big turnoff.

The other important reason for “enqueuing” scripts into the footer is so that scripts can access the DOM page elements, which are often required as some scripts search for selectors on the page such as with jQuery.

How do scripts load normally on a web page?

So what happens as a page loads. Before I dive right in, I’d like to say that I am not an expert on this, so if I get something a little wrong, or a lot wrong, then leave a comment and explain it better for us all.

Ok so when the browser starts to render the page it parses the HTML. When a script is detected, the HTML parsing pauses while the script loads and executes. This means that if you have lots of scripts loading in the header, it holds up the page and so it may look like nothing is happening, and that might mean nothing for the viewer to look at!

Using Async or Defer

If we use the “async” option for loading a script file, then when the page loads, HTML parsing is not interrupted as the scripts are fetched (that is they load while the page continues to load), but once the script has finished loading it executes immediately.

While the script executes, HTML parsing is again stopped. However this still means a better user experience, and so using “async” is good for scripts that don’t depend on HTML elements loading first, or what order other scripts are loaded. So if you are loading a Google+ button then that’s fine to use “async” but if you are loading a slider that relies on jQuery script to have loaded first, then using “async” can cause some script issues.

An alternative, and the way that I prefer to load most of the scripts on a WordPress page, is to use “defer“. When you include “defer” in your enqueued script, then the scripts load at the same time that HTML parsing is happening. Then they wait until the page has finished loading, before executing. This means that the page is loaded first, then the scripts run.

What is also important is that they execute in the order they appeared. So if one script relies on another, such as those scripts that rely on jQuery, then your web page will still work the way you hoped!

This is what a defer script call looks like

 <script src="demo_defer.js" defer></script>

Not all is perfect in the browser world

Ok it’s important to add a warning here. Not always do things go the way they are supposed to. As you probably guessed – some browser versions do not play nice and can be erratic with how they “defer”. Thankfully though most modern browser versions do support “defer” correctly.

But always test yourself on different browsers, and if you notice any issues then inspect the javascript loading to see what is the culprit.

A defer code snippet for enqueued scripts in WordPress

The following function is what I use to add defer to enqueued scripts in WordPress. You will note below that I don’t defer for admin scripts, for jQuery itself, or for Internet Explorer 9.

//to add defer to loading of scripts - use defer to keep loading order
function script_tag_defer($tag, $handle) {
    if (is_admin()){
        return $tag;
    }
    if (strpos($tag, '/wp-includes/js/jquery/jquery')) {
        return $tag;
    }
    if (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 9.') !==false) {
	return $tag;
    }
    else {
        return str_replace(' src',' defer src', $tag);
    }
}
add_filter('script_loader_tag', 'script_tag_defer',10,2);

For more reading please checkout the following resources:
growingwiththeweb.com/2014/02/async-vs-defer-attributes
developers.google.com/speed/docs/insights/BlockingJS

Print a nice copy of this page for reference

Using Defer or Async with scripts in WordPress was last modified: September 6th, 2016 by David Tiong
Using Defer or Async with scripts in WordPress