Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

lazy loading javascript [closed]

What is the basic difference between this 3 ways for lazy loading js or ondemand loading and why?

script 1:

$.getScript = function(url, callback, cache){
   $.ajax({
      type: "GET",
      url: url,
      success: callback,
      dataType: "script",
      cache: cache
   });
};

script2:

function require(file, callback) {
    var script = document.getElementsByTagName('script')[0],
        newjs = document.createElement('script');

    // IE
    newjs.onreadystatechange = function () {
        if (newjs.readyState === 'loaded' || newjs.readyState === 'complete') {
            callback();
        }
    };

    // others
    newjs.onload = function () {
        callback();
    };

    newjs.src = file;
    script.parentNode.insertBefore(newjs, script);
}

document.getElementById('id').onclick = function () {
    require('ondemand.js', function () {
        extraFunction('loaded from the parent page');
        document.body.appendChild(document.createTextNode('done!'));
    });
};

script3:

$L = function (c, d) {
    for (var b = c.length, e = b, f = function () {
            if (!(this.readyState
                    && this.readyState !== "complete"
                    && this.readyState !== "loaded")) {
                this.onload = this.onreadystatechange = null;
                --e || d()
            }
        }, g = document.getElementsByTagName("head")[0], i = function (h) {
            var a = document.createElement("script");
            a.async = true;
            a.src = h;
            a.onload = a.onreadystatechange = f;
            g.appendChild(a)
        }; b;) i(c[--b])
};
like image 948
paul Avatar asked Aug 18 '11 18:08

paul


4 Answers

  1. Uses ajax to load the script. More specifically it uses XHR to load some js and have it available to the browser. No blocking is done. It does still enforce the same origin policy.
  2. Modifies the header to inject a new .js file by creating <script/> element. This also doesn't block the browser on page load.
  3. Does the same thing as #2 but it seems to support an array of scripts. It also sets async to true which causes no blocking. The for loop is just more confusing because it creates a lot more anonymous methods.
like image 105
Amir Raminfar Avatar answered Oct 05 '22 22:10

Amir Raminfar


  1. Seems to retrieves the script with a XmlHttpRequest and eval() it. This won't work if the script is not hosted on the same protocol / domain / port.

  2. and 3. seems to both do the same thing: they create a <script src="the script url"></script> element, bind onload events on it and insert it on the page. The script is executed by the browser once it is loaded, and the onload event is fired.

like image 20
Arnaud Le Blanc Avatar answered Oct 05 '22 23:10

Arnaud Le Blanc


  1. Gets the script via ajax, and eval()'s the contents
  2. Insert a script element into the head element and report back when it has loaded
  3. Same as (2) but accept and array of script urls, and is way more complexly written

(2) and (3) both use the onreadystatechange hook, which may not be compatible with older browsers (for instance, Firefox 3.x and below doesn't support it).

(1) is probably the most robust, compatibility-wise, since it just requires XHR. But if you get errors in the code you load that way, the browser's console may not be very helpful, as the error just occurred in "eval'd code" and not in a specific file/line. That said, lazy loading is typically an optimization thing, so you can just include the scripts normally, or with any of the other 2 methods, while debugging.

like image 31
Flambino Avatar answered Oct 05 '22 23:10

Flambino


you should try this new library called head.js

they have some interesting ideas and apis.. hope it helps.

or what you can do is use the normal xhr request to get your script file names and use a method like this to insert into the dom.. I have added the removeScript part too.

addScript = function(file)
{
    var headID = document.getElementsByTagName("head")[0];         
    var newScript = document.createElement('script');
    newScript.type = 'text/javascript';
    newScript.src = file;
    headID.appendChild(newScript);
};
removeScript = function(file)
{
    var headID = document.getElementsByTagName("head")[0].children;
    for(var i in headID)
        if(headID[i].tagName == "SCRIPT")
            if(headID[i].getAttribute('src') == file)
                headID[i].parentNode.removeChild(headID[i]);
}

if you are using a library like jquery you dont need to worry about anything you can get the html or script markup from the server and use .html() api to in insert it into the dom

like image 35
Baz1nga Avatar answered Oct 05 '22 22:10

Baz1nga