Lazyload (Asynchronous loading) your javascript files

An alternative to putting scripts on the bottom, is to lazyload your scripts. To lazyload your scripts there are three ways i want to show you. First you can write your own little script that will asynchronously load your main javascript file by inserting the script tag for that file programmatically. Second possibility is to use a tool like require.js which is an asynchronous scripts downloader. The thrid possibility is the new HTML5 attribute for the script tag that you can use to force the browser to load the script asynchronously.

Lazyloading a javascript file default

You can create your own basic lazyloader yourself. Only a few lines of javascript in the head of your document and your done:


function lazyload() {
    var scriptTag = document.createElement('script'); 
    scriptTag.src = "//my_example.js"; // set the src attribute
    scriptTag.type = 'text/javascript'; // if you have an HTML5 website you may want to comment this line out
    scriptTag.async = true; // the HTML5 async attribute
    var headTag = document.getElementsByTagName('head')[0];
    headTag.appendChild(scriptTag);
}

To launch it when the page finished loading you could add a body tag like the following one to your page:

<body onload="lazyload();">

This script is small and easy to understand. You can hack it to make it load multiple files.

Lazyloading a javascript files using require.js

I really like require js. It has more advantages then just loazyloading your javascipt files, but this is the part i will cover here as this article is about asynchronous javascript loading.

Lets say you want to get started with require js, you want to load three scripts, the first one is the jQuery javascript library, the second one is the jQuery mobile plugin and the third file is your own application module, with require js you would do something like this (this is my main.js file content):


// configure the path to my three javascript files
// 
// the key is the name of the file as it will be used inside of our application
// the value is the filename without the extension that you can omit
require.config({

    paths : {
        'jquery' : 'jquery-1.8.2',
        'jquery.mobile' : 'jquery.mobile-1.2.0',
        'chris.application' : 'chris.application-1.0.1'
    }

});


// tel require js that we want to load jQuery and application
// we don't load jQuery mobile here because we need jQuery to be 
// defined (loaded) before we load jquery mobile
//
// jquery mobile will not like jQuery wait for a page onload event, it 
// will fire as soon as it is loaded, that's why we load it after
// jQuery to ensure jQuery is defined
//
// we tell require js to load out to files by using their name as
// we have defined it in the configuration
//
// finally we start our main function with as parameters the alias
// we want to use for the code we just loaded, jQuery always uses the dollar sign
// so we will use the same, and for our application code we use "application"
// as alias
require(['jquery', 'chris.application'], function($, application) {

    // some jQuery code i didn't want to put in application-1.0.1.js
    $('#someButton').on('click', function(event) {

        console.log('button clicked');

    });

    // now that require js has loaded jQuery we can also load jQuery mobile
    require(['jquery.mobile'], function(){

        $('body').addClass('chris');

	// now that everything got loaded we can start the application
        application.initialize();

    });

});

Now that you saw the content of your main.js file, the only still you need to make it work is the require js tag, that you place in the head of your document. What it does is, it loads require js, which then lazyloads your main.js file or whatever javascript file you specify in its data attribute:

<script data-main="//js/main-1.0.1" src="//js/require-2.0.6.min.js"></script>

This will load require js from js directory, which will then load main-1.0.1.js from the same directory. Like inside a require js file, when you tell require.js the path to your main javascript file you can omit the extension.

the HTML5 async attribute

<script async src="//example.com/someScript.js"></script>

for more information about the async attribute you may want to read the w3c HTML5 specification chapter that covers the new async attribute. If you want to know which browsers support it, check out caniuse.com

Loading scripts asynchronously has several advantages. The first an major one is that the loading of the scripts won't block your page from rendering content, because while downloading javascript your browser halts the page rendering process. The second one is that the downloading of other important files like your css files or images will get blocked while your javascript is downloading. If you load external files (social buttons javascript, advertising javascript, ...) asynchronously it has the advantage that it won't slow down your own page if the third party server is slow or unavailable at all.

A disadvantage is that you have to check if the javascript code you want to use in your function already got loaded or if it is still underway.