Lazy Javascript Loader

Richard Wong 30 March, 2010

I was involved in a project recently with some heavy use of Javascript. We needed to load many javascript files on the page. Because of the site structure and the legacy system, there are potential situations where the same javascript is loaded more than once. To over come that, we needed something that can handle the script loading for us.

After looking at many options, we decided to write our own quick and dirty lazy script loader which will fit our need.

The key features we want from it are:

  • Dynamically creating a script tag to load any scripts we want
  • Handle callbacks
  • Handle duplicate script load
  • Small in size and simple api
  • Framework independent

Usage Example:

ScriptLoader.load('demo.js', function() {
    alert('Demo script loaded Loaded');
});

Code:

//namespace
var ScriptLoader = {}; 

//scripts object storing the state and callbacks of scripts
ScriptLoader.scripts = {}; 

//Handle multiple script callbacks to one single script
ScriptLoader.onScriptLoad = function(url) {
        var script = this.scripts[url];
        script.loaded = true;
        for (var i = 0, len = script.callbacks.length; i < len; i++)
        {
                var callback = script.callbacks[i];
                if (typeof callback != 'undefined') callback();
        }
};

//Main loader function
ScriptLoader.load = function(url, callback) {

        //Check if script has already been added to the loader
        if (this.scripts[url] != undefined)
        {
                if (this.scripts[url].loaded) //File loaded
                {
                        //Run callback straight away
                        if (typeof callback != 'undefined') callback();
                }
                else //Still loading
                {
                        //Add callback to list for running later
                        this.scripts[url].callbacks.push(callback);
                }

                //Script already requested so exit here
                return;
        }

        //Create tracker for this script to monitor status and build a list of callbacks
        this.scripts[url] = {loaded: false, callbacks: [callback]};

        //Add script element to DOM and add onload handlers for callbacks
        var script = document.createElement("script")
        script.type = "text/javascript";

        if (script.readyState) //IE
        {
                script.onreadystatechange = function()
                {
            if (script.readyState == "loaded" ||
                    script.readyState == "complete")
                        {
                script.onreadystatechange = null;

                                ScriptLoader.onScriptLoad(url);
                        }
        };
    }
   else //Other browsers
   {
            script.onload = function(event)
            {
                        ScriptLoader.onScriptLoad(url);
           };
    }

    script.src = url;
    document.getElementsByTagName('head')[0].appendChild(script);
};

This is by no mean to be ground breaking or prefect but it is working prefect for us on most popular browsers. There are many awesome fully featured script loading library out there. RequireJS is definitely one worth looking.

I also have to thanks Charles Davison co-author of the code and Bob Matsuoka as he gave us a good starting point for this script in his A Technique For Lazy Script Loading article from Ajaxian

Comments so far

  1. dropshippers April 7th, 2011 at 5:58 am

    Does this script stop multiple javascript files from conflicting? I’m having a problem on my site where only one script will work on the page.

  2. Richard Wong April 11th, 2011 at 9:23 pm

    It will only load the same script once as it will record all the scripts being loaded. But if there are conflicts in with different script, then there are not much this script can do…

  3. Isabelle Long April 15th, 2011 at 12:36 pm

    Thanks for this Javascript Loader. Might as well try it to upload.

Post a comment