Speed Defer Loading Javascript

defer javascript

Deferring of javascript is one of those issues on the web that can make you want to pull your hair out trying to find a solution.

Many people say "just use defer" or "just use async" or others say "just put your javascript at bottom of page".

None of the above are solutions to the problem of actually allowing a webpage to fully load and then (and only then) loading external JS. Nor will any of the above always get you past that "Defer loading of javascript" warning you are getting from the Google page speed tool. This solution will and is the recommended solution from the Google help pages.

How to defer loading of javascript

The below code is what Google recommends. This code should be placed in your HTML just before the </body> tag (near the bottom of your HTML file). I highlighted the name of the external JS file.

<script type="text/javascript">
function downloadJSAtOnload() {
var element = document.createElement("script");
element.src = "defer.js";
document.body.appendChild(element);
}
if (window.addEventListener)
window.addEventListener("load", downloadJSAtOnload, false);
else if (window.attachEvent)
window.attachEvent("onload", downloadJSAtOnload);
else window.onload = downloadJSAtOnload;
</script>

What does this do?

This code says wait for the entire document to load, then load the external file "defer.js".

Specific instructions

1. Copy above code.

2. Paste code in your HTML just before the </body> tag (near the bottom of your HTML file).

3. Change the "defer.js" to the name of your external JS file.

4. Ensure the path to your file is correct. Example: if you just put "defer.js", then the file "defer.js" must be in the same folder as your HTML file.

What you can use this code for (and what you can not)

This code will not load the external file you specify until after the document has loaded. Because of this you should not put any javascript in there that is needed for the page to load properly. You should separate your javascript into two groups. One group is the javascript the page needs to load and the the second group is the javascript that is doing stuff after the page loads (like looking for click events or something). The javascript that can wait until after the page loads should be all put into the one external file you are calling above.

For example, on this page I use the above file to defer - Google analytics, Viglink (how I make money), and the Google plus badge that is displayed in my footer (my social media). There are no reasons for me to load these files for the initial page load because none of them are necessary to load the above the fold content. You probably have the same type of stuff on your pages. Are you making your users wait to load these before showing them your content?

Why don't the other methods work?

The methods of inlining, placing scripts at the bottom, using "defer" or using "async" all do not accomplish the goal of letting the page load first then loading JS and they certainly do not work universally and cross browser.

Why does it matter?

It matters because Google is judging page speed as a ranking factor and because users want fast loading pages. Google measures your page speed from the the time it is called to when the page is initially loaded. This means you want to get to the page load event as quickly as possible. That initial page load time is what Google is using to judge your webpage (and let's not forget your users waiting for it to load). Google actively promotes and recommends prioritizing above the fold content so getting any resources at all (js, css, images, etc.) out of the critical rendering path is well worth the effort. If it makes your users happy, and it makes Google happy, you should probably do it.

Example usage

I have created a page here that you can see using the code.

Example files for your testing

Okay, just to illustrate I have made some example pages for you to play with. Each page does the same thing. It is a plain HTML page that uses one script that waits two seconds then says "hello world". You can test these and see that only one method will register a load time that does not include the 2 second wait.

Key point

The overwhelming priority should be placed on delivering the content to the user as soon as possible. We have not been doing that with how we have treated our javascript. A user should not have to wait to see their content because of some script that is likely doing something to below the fold content. No matter how cool your footer is, there really is no reason for a user who may never even scroll down to your footer to load the javascript that makes your footer cool.

Patrick Sextonby Patrick Sexton