How to “Really” defer loading of JavaScript?

The websites nowadays uses a LOT of JavaScript. However, defer loading of JavaScript is actually a big headache as there’s really, really many ways to do it. Someone may call you “just use defer” or “just use async” or even “just put it on the bottom of the page”.

Actually, none of these methods really solve the problem that allows a page to be fully loaded before loading scripts. None of these methods actually gets passed of the “Defer loading of scripts” if you’re trying to test it with Google PageSpeed.

The right way

In here, I’ll show you the right method of defer loading JavaScript that Google also recommends.

Beware: You should put this just before </body> (near the end of an HTML file)

<script type="text/javascript">
function downloadJSAtOnload() {
    var element = document.createElement("script");
    element.src = "defer.js"; // replace defer.js with your script instead
    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 it really does is to load the JavaScript after the page has been fully load i.e. The onload event has been triggered.

Why the other methods don’t 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.

Speed

defer-methods

You can see that with this method, the page load speed has a very great increase. As the other methods don’t match the goal of loading JavaScript only after the page has finished loading, it can be very slow especially for large JS files.

Final word

Our first priority is to deliver the content to the user as soon as possible. If a user waits because there’s some JavaScripts still loading that doesn’t affect the content, the user may leave because of the long waiting. (The average wait time for a visitor is around 2 – 3 seconds) Therefore, you should remember the right method of deferring JavaScript loading.

Turn asynchronous functions to their synchronous counterpart

Recently, asynchronous programming becomes a hit as slow jobs can perform while not blocking other jobs to be done. However, sometimes we want something to be done in a synchronous way like getting a single value from a query (you know callbacks are clumsy). In order to solve the  problem, turning asynchronous functions to synchronous can solve the problem.

To turn asynchronous functions to synchronous, we need to set up a loop checking the result, therefore cause blocking.

Here’s the code: (we use javascript here because it’s straightforward)

function somethingSync(args){
    var ret; //the result-holding variable
    //doing something async here...
    somethingAsync(args,function(result){
        ret = result;
    });
    while(ret === undefined){} //wait for the result until it's available, cause the blocking
    return ret;
}