75

Let's face it, jQuery/jQuery-ui is a heavy download.

Google recommends deferred loading of JavaScript to speed up initial rendering. My page uses jQuery to set up some tabs which are placed low on the page (mostly out of initial view) and I'd like to defer jQuery until AFTER the page has rendered.

Google's deferral code adds a tag to the DOM after the page loads by hooking into the body onLoad event:

<script type="text/javascript">

 // Add a script element as a child of the body
 function downloadJSAtOnload() {
 var element = document.createElement("script");
 element.src = "deferredfunctions.js";
 document.body.appendChild(element);
 }

 // Check for browser support of event handling capability
 if (window.addEventListener)
 window.addEventListener("load", downloadJSAtOnload, false);
 else if (window.attachEvent)
 window.attachEvent("onload", downloadJSAtOnload);
 else window.onload = downloadJSAtOnload;

</script>

I'd like to defer loading of jQuery this way, but when I tried it my jQuery code failed to find jQuery (not completely unexpected on my part):

$(document).ready(function() {
    $("#tabs").tabs();
});

So, it seems I need to find a way to defer execution of my jQuery code until jQuery is loaded. How do I detect that the added tag has finished loading and parsing?

As a corollary, it appears that asynchronous loading may also contain an answer.

Any thoughts?

Kevin P. Rice
  • 5,550
  • 4
  • 33
  • 39
  • Why not just include jQuery (and your own JS file(s)) at the bottom of your page rather than in the head? – Kevin Ennis May 02 '11 at 01:42
  • 2
    Google says (in the first link I provided), "scripts must be downloaded, parsed, and executed before the browser can begin to render a web page". This means loading jQuery at the bottom of the page means that the page is still is not rendered until jQuery is parsed and executed. Is there a way to load it asynchronously and let it do it's job after the page loads? – Kevin P. Rice May 02 '11 at 01:58
  • 1
    Can't you `defer` all your external scripts? They are supposed to still execute in the order listed. – nilskp Oct 14 '12 at 00:15
  • 2
    @nilskp It seems there would be an existing and accepted best-practice for this question, which is why I presented it, rather than attempt to roll my own. There are tons of pitfalls in this area with all the various browsers out there. – Kevin P. Rice Oct 14 '12 at 04:59
  • If you defer all scripts they will (or at least should) be loaded in the same order, just simply loaded when the browser deems it optimal to do so. async however, will allow the js files to load in any order the browser sees fit. Therefore you shouldn't have any issues if you defer all script files including JQuery libraries. – Phill Healey Aug 23 '16 at 09:40
  • I once `async` both jQuery and my script. My script checked the existence of `window.jQuery`. If it doesn't exists, it will attach a load-listener to jQuery tag. https://github.com/johnchen902/toyoj/blob/99bf5ef0699f29e9c5164a10f6820f81876f9fd5/web/public/toyoj.js – johnchen902 Oct 07 '17 at 23:02
  • I started doing this and then switched to Vanilla JS. I literally just told VS Code (Codex) "translate all this from jQuery to Vanilla JS" – William Entriken Mar 10 '23 at 14:55

17 Answers17

54

Try this, which is something I edited a while ago from the jQuerify bookmarklet. I use it frequently to load jQuery and execute stuff after it's loaded. You can of course replace the url there with your own url to your customized jquery.

(function() {
      function getScript(url,success){
        var script=document.createElement('script');
        script.src=url;
        var head=document.getElementsByTagName('head')[0],
            done=false;
        script.onload=script.onreadystatechange = function(){
          if ( !done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete') ) {
            done=true;
            success();
            script.onload = script.onreadystatechange = null;
            head.removeChild(script);
          }
        };
        head.appendChild(script);
      }
        getScript('http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js',function(){
            // YOUR CODE GOES HERE AND IS EXECUTED AFTER JQUERY LOADS
        });
    })();

I would really combine jQuery and jQuery-UI into one file and use a url to it. If you REALLY wanted to load them separately, just chain the getScripts:

getScript('http://myurltojquery.js',function(){
        getScript('http://myurltojqueryUI.js',function(){
              //your tab code here
        })
});
ampersand
  • 4,264
  • 2
  • 24
  • 32
  • Looks like the fancy version of tylermwashburn's suggestion. By deferring everything, I think it sets up a dependency-order problem: MyCode relies on JQueryUI relies on JQuery. Thus, some code to load each--in proper order--is needed. You have given me some ideas. – Kevin P. Rice May 02 '11 at 04:13
  • 1
    actually, this is completely different from tylermwashburn's suggestion. What this does for you is load jQuery and then load jQuery ui and THEN executes your jquery/jqueryUI-dependent code, which is what you asked for...this code is cross-browser (which is why it looks 'fancy') and works every time for me. As for the DOMready code, I just realized that it might be a little old and I'd not use it. I think I have an updated domready somewhere's...let me find it. – ampersand May 02 '11 at 04:21
  • tyler's suggestion is good. What I would do is make the chained getscripts the callback of the body load event – ampersand May 02 '11 at 04:44
  • Yes, I see the differences--but similarly it's waiting for onload/onreadystatechange event. ALSO: I don't think DOMready is necessary since jQuery provides it, right? As long as dependencies are satisfied by loading the scripts in order, I'm guessing the jQuery .ready() method would hold off execution in the off-chance that all the scripts loaded before DOMready occurred. – Kevin P. Rice May 02 '11 at 04:52
  • what I was attempting with the DOMready bit there was to provide a solution for this part of your question:"...defer jQuery until AFTER the page has rendered." If you want to defer these getScripts() until after the page has rendered, you'll need to FIRST have a domready alternative, because you can't use jQuery's...because you're loading jQuery AFTER. Anyway, I think this is unecessary for your purposes. If you bind to body's load event, I think you'll get what you're looking for. – ampersand May 02 '11 at 04:59
  • @ampersand, Actually jQuery's .ready() method would be available--let me explain... I'm only trying to load scripts deferred/async so that the browser doesn't hold up the page render and user experience; however, I'm not necessarily trying to ensure DOMready before loading jQuery (even though I think body load may be a near equivalent). I just need to ensure all the scripts load in the right order--and if that happens, jQuery's .ready() method will be available since it loads first! Perhaps I should look for event earlier than body load (which may be DOMready)? Chicken or the egg... – Kevin P. Rice May 02 '11 at 05:29
  • 6
    I have used this with great success. I have also modified the `success();` on line 10 to be `if(success && getClass.call(success) == '[object Function]') { success(); }`. This executes the success function **only** if it's not null and it's a function. This allows you to just call `getScript("myScript.js")` without a function call. – Dan Atkinson Mar 27 '13 at 13:44
  • @DanAtkinson shouldn't that be getScript instead of getClass in your code? Can we use the script for deferring multiple Js files (not only Jquery), do they have to be depended. – Geniusknight Jul 24 '14 at 17:12
  • 1
    @Geniusknight Yes, it's getScript()! :) It can be used for deferring more than one, and if there are dependencies, you'll need to code for them to ensure that they're loaded before you attempt to run any child scripts that depend on it. Using a multi-dimensional array would be a fairly simple way of doing this. – Dan Atkinson Jul 24 '14 at 21:51
  • Great! Now I can get things moving . hehe :D Have a nice day! – Geniusknight Jul 24 '14 at 22:09
  • A simple question... when we call scripts like that, the browser will still use cache? – Paulo Lima Sep 10 '19 at 20:08
14

As this is a top ranking question on a important subject let me be so bold to provide my own take on this based on a previous answer from @valmarv and @amparsand.

I'm using a multi-dimensional array to load the scripts. Grouping together those that have no dependencies between them:

var dfLoadStatus = 0;
var dfLoadFiles = [
      ["http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"],
      ["http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.11/jquery-ui.min.js",
       "/js/somespecial.js",
       "/js/feedback-widget.js#2312195",
       "/js/nohover.js"]
     ];

function downloadJSAtOnload() {
    if (!dfLoadFiles.length) return;

    var dfGroup = dfLoadFiles.shift();
    dfLoadStatus = 0;

    for(var i = 0; i<dfGroup.length; i++) {
        dfLoadStatus++;
        var element = document.createElement('script');
        element.src = dfGroup[i];
        element.onload = element.onreadystatechange = function() {
        if ( ! this.readyState || 
               this.readyState == 'complete') {
            dfLoadStatus--;
            if (dfLoadStatus==0) downloadJSAtOnload();
        }
    };
    document.body.appendChild(element);
  }

}

if (window.addEventListener)
    window.addEventListener("load", downloadJSAtOnload, false);
else if (window.attachEvent)
    window.attachEvent("onload", downloadJSAtOnload);
else window.onload = downloadJSAtOnload;

It loads first jquery after it is loaded it continue to load the other scripts at once. You can add scripts easy by adding to the array anywhere on your page:

dfLoadFiles.push(["/js/loadbeforeA.js"]);
dfLoadFiles.push(["/js/javascriptA.js", "/js/javascriptB.js"]);
dfLoadFiles.push(["/js/loadafterB.js"]);
Pevawi
  • 189
  • 2
  • 3
  • Is this still necessary with async and/or defer attribute on – HHeckner Feb 21 '21 at 09:42
13

Here is a good description of modern approach for async/defer javascript loading. But it doesn't works for inline scripts

<script type="text/javascript" src="/jquery/3.1.1-1/jquery.min.js" defer></script>
<script type="text/javascript" defer>
    $(function () {   //  <- jquery is not yet initialized
      ...
    });
</script>

The simplest solution for async loading was suggested by @nilskp - externalize script:

<script type="text/javascript" src="/jquery/3.1.1-1/jquery.min.js" defer></script>
<script type="text/javascript" src="resources/js/onload.js" defer></script>
Community
  • 1
  • 1
Grigory Kislin
  • 16,647
  • 10
  • 125
  • 197
4

I add this piece of code after the async/defered jquery script tag, this defines a temporary function $ that will accumulate whatever it is that needs to run when everything is done loading, and then once we're done use $ that by this time would be overwritten to execute the functions. With this piece of code there's no need to change the jQuery onload syntax further down in the document.

<script defer async src="https://code.jquery.com/jquery-2.2.0.min.js">
<script>
    var executeLater = [];
    function $(func) {
        executeLater.push(func);
    }
    window.addEventListener('load', function () {
        $(function () {
            for (var c = 0; c < executeLater.length; c++) {
                executeLater[c]();
            }
        });
    })
</script>

....and then...

<script>
    $(function() {
        alert("loaded");
    });
</script>
asiop
  • 707
  • 4
  • 11
3
element.addEventListener("load", function () {
    $('#tabs').tabs()
}, false);

Try that.

McKayla
  • 6,879
  • 5
  • 36
  • 48
  • Yep! You've got it! So, I think some combination of this and "ampersand's" answer will be the final solution. It appears I will need to chain-load jQuery, then jQuery-UI, then my page code which relies on both. – Kevin P. Rice May 02 '11 at 04:24
  • 1
    IE<9 does not support addEventListener :( – brunoais Feb 20 '12 at 13:34
2

In certain situation you could fire an event when jquery is loaded.

<script type="text/javascript">
    (function (window) {

        window.jQueryHasLoaded = false;

        document.body.addEventListener('jqueryloaded', function (e) {
            console.log('jqueryloaded ' + new Date() );
        }, false);

        function appendScript(script) {
            var tagS = document.createElement("script"), 
                s = document.getElementsByTagName("script")[0];
            tagS.src = script.src;
            s.parentNode.insertBefore(tagS, s);

            if ( script.id == 'jquery' ) {
                tagS.addEventListener('load', function (e) {
                    window.jQueryHasLoaded = true;
                    var jQueryLoaded = new Event('jqueryloaded');
                    document.body.dispatchEvent(jQueryLoaded);
                }, false);
            }
        }

        var scripts = [
            {
                'id': 'jquery',
                'src': 'js/libs/jquery/jquery-2.0.3.min.js'
            },
            {
                'src': 'js/myscript1.js'
            },
            {
                'src': 'js/myscript2.js'
            }
        ];

        for (var i=0; i < scripts.length; i++) {
            appendScript(scripts[i]);
        }

    }(window));
</script>

Then wrap your dependencies in a function:

// myscript1.js 
(function(){ 

    function initMyjQueryDependency() {
        console.log('my code is executed after jquery is loaded!');
        // here my code that depends on jquery
    }

    if ( jQueryHasLoaded === true )
        initMyjQueryDependency();
    else
        document.body.addEventListener('jqueryloaded', initMyjQueryDependency, false);

}());

If jquery finishes to load after the other scripts, your dependencies will be executed when the jqueryloaded event is fired.

If jquery is already loaded, jQueryHasLoaded === true, your dependency will be executed initMyjQueryDependency().

mex23
  • 111
  • 2
  • 7
2

Put jQuery and your jQuery dependent code at the end of your HTML file.

Edit: A little more clear

<html>
<head></head>
<body>
    <!-- Your normal content here -->
    <script type="text/javascript" src="http://path/to/jquery/jquery.min.js"></script>
    <script>//Put your jQuery code here</script>
</body>
</html>
Dan
  • 885
  • 6
  • 11
  • 3
    That seems to be the "next best" solution, but it's not really the same. While it does allow other resources to load, Google says (in the first link I provided), "scripts must be downloaded, parsed, and executed before the browser can begin to render a web page". This means loading jQuery at the bottom of the page means that the page is still is not rendered until jQuery is parsed and executed. Is there a way to load it asynchronously and let it do it's job **after** the page loads? – Kevin P. Rice May 02 '11 at 01:56
  • 2
    This would be super easy to test. Make yourself a nice big 10MB JS file filled with nonsense and include it at the bottom of your page. See if your other content loads first. – Kevin Ennis May 02 '11 at 02:00
  • kennis--YES the other content loads first, however, the question pertains to user experience. On mobile browsers especially, the time to parse JavaScript delays the user being able to interact with the page. In Chrome developer tools, the "Evaluate Script" timeline for jQuery is HALF of the time before the DOMContentLoaded and Load events fire. The script that I am able to defer with the Google code (in the question) does not load or execute until AFTER these events. I'd like jQuery to load/parse AFTER the page renders. – Kevin P. Rice May 02 '11 at 02:11
  • @Kevin, The link also states that "...processing of all elements **below the script** is blocked until the browser loads the code from disk and executes it." At least with desktop browsers, the user can start interacting with the page before the page is fully loaded. What's the load time difference from initial request until the user can interact with the page (not necessarily the DOMContentLoaded event) with your scripts at the bottom and no script at all? – Dan May 02 '11 at 02:28
  • I would definitely "benchmark" (as best as you can) both methods to make sure the async is loading faster. Looks like Jeremy has the code you were originally looking for. Good luck! – Dan May 02 '11 at 02:47
  • @Dan, Drackir's code illustrates my problem precisely, which is how to delay the code next to "<=== NOTE THIS" until AFTER jQuery is loaded ("deferredfunctions.js"). Putting all – Kevin P. Rice May 02 '11 at 03:09
1

Here's my version which supports chaining to be sure the scripts are loaded one after each other, based on ampersand's code:

var deferredJSFiles = ['jquery/jquery', 'file1', 'file2', 'file3'];
function downloadJSAtOnload() {
    if (!deferredJSFiles.length)
        return;
    var deferredJSFile = deferredJSFiles.shift();
    var element = document.createElement('script');
    element.src = deferredJSFile.indexOf('http') == 0 ? deferredJSFile : '/js/' + deferredJSFile + '.js';
    element.onload = element.onreadystatechange = function() {
        if (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete')
            downloadJSAtOnload();
    };
    document.body.appendChild(element);
}
if (window.addEventListener)
    window.addEventListener('load', downloadJSAtOnload, false);
else if (window.attachEvent)
    window.attachEvent('onload', downloadJSAtOnload);
else
    window.onload = downloadJSAtOnload;
valmarv
  • 854
  • 1
  • 8
  • 14
1
<!doctype html>
<html>
    <head>

    </head>
    <body>
        <p>If you click on the "Hide" button, I will disappear.</p>
        <button id="hide" >Hide</button>
        <button id="show" >Show</button>

        <script type="text/javascript">
            function loadScript(url, callback) {

                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;
                            callback();
                        }
                    };
                } else {  //Others
                    script.onload = function() {
                        callback();
                    };
                }

                script.src = url;
                document.body.appendChild(script);
            }
            loadScript("http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js",
                    function() {
                        //YAHOO.namespace("mystuff");
                        $("#show").click(function() {
                            $("p").show();
                        });
                        $("#hide").click(function() {
                            $("p").hide();
                        });

                        //more...
                    });
        </script>

    </body>
</html>
Nanhe Kumar
  • 15,498
  • 5
  • 79
  • 71
1

I think Modernizr.load() is worth a mention here - it handles dependency loading very nicely

Mike
  • 628
  • 10
  • 22
1

The following code should load your scripts after the window is finished loading:

<html>
<head>
    <script>
    var jQueryLoaded = false;
    function test() {
        var myScript = document.createElement('script');
        myScript.type = 'text/javascript';
        myScript.async = true;
        myScript.src = jQueryLoaded ? 'http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.js' : 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.11/jquery-ui.min.js';
        document.body.appendChild(myScript);

        if(!jQueryLoaded){
            alert('jquery was loaded');
            jQueryLoaded = true;
            test();
        } else {
            alert('jqueryui was loaded');   
        }
    }

    if (window.addEventListener){
        alert('window.addEventListener');
        window.addEventListener("load", test, false);
    } else if (window.attachEvent){
        alert('window.attachEvent');
        window.attachEvent("onload", test);
    } else{
        alert('window.onload');
        window.onload = test;
    }
    </script>
</head>
<body>
<p>Placeholder text goes here</p>
</body>
</html>

Worked for me in Chrome, FF and IE9 - let me know if that helps

Jeremy Battle
  • 1,638
  • 13
  • 18
  • Jeremy, thanks--however see my reply to kennis (above). I'd like jQuery to load/evaluate/parse/execute AFTER the page is loaded. – Kevin P. Rice May 02 '11 at 02:13
  • Edited my response to accomplish loading the scripts after the window.load/onload event has fired – Jeremy Battle May 02 '11 at 02:33
  • Jeremy, again thanks--I'm going to try the 'async' property... however, see the code 'Drackir' posted below which is EXACTLY what I tried. Result: YES, jQuery loads deferred, but the 'tabs' code (same as how Drackir shows it) doesn't wait for the deferred jQuery.js to load and I get "jquery undefined". Somehow, I need a callback or event to know when jquery.js is loaded and parsed. – Kevin P. Rice May 02 '11 at 02:41
  • A bit of a hack, but you could technically do a busy-wait loop and check to see if jQuery is loaded before running **$("#tabs").tabs();**. If it's not, do a setTimeout and call the function again. – Dan May 02 '11 at 02:59
  • 1
    Kevin, edited one more time. Worked for me let me know if it works for your tabs. – Jeremy Battle May 02 '11 at 03:01
  • Jeremy, I'm building on your suggestion...will post back soon. It turns out "if($)" tests for jQuery, and "if($.ui)" tests for jQuery-UI... you can see where I'm going. Although "polling" (busy-wait loop) is kludgy. I'd prefer to find an event to hook into. – Kevin P. Rice May 02 '11 at 03:26
  • @Jeremy, it looks like 'ampersand' has ultimately pointed out the events that can be hooked into and shown how to chain multiple scripts together. – Kevin P. Rice May 02 '11 at 04:56
1

Well it seems to me, all you have to do is either a) add the jQuery code you want to run on load, to the end of the jQuery file or b) append it to the downloadJSAtOnload function like so:

<script type="text/javascript">

 // Add a script element as a child of the body
 function downloadJSAtOnload() {
 var element = document.createElement("script");
 element.src = "deferredfunctions.js";
 document.body.appendChild(element);
 $("#tabs").tabs(); // <==== NOTE THIS. This should theoretically run after the
                    // script has been appended, though you'll have to test this
                    // because I don't know if the JavaScript above will wait for
                    // the script to load before continuing
 }

 // Check for browser support of event handling capability
 if (window.addEventListener)
 window.addEventListener("load", downloadJSAtOnload, false);
 else if (window.attachEvent)
 window.attachEvent("onload", downloadJSAtOnload);
 else window.onload = downloadJSAtOnload;

</script>
  • This is EXACTLY what I tried. It DOES NOT wait to load the "deferredfunctions.js" (which I replaced with jQuery.js) before executing the 'tabs' code. So, how to get the 'tabs' code to wait for jQuery?? I could put it into the same file, but not if I'm loading jQuery from Google CDN. – Kevin P. Rice May 02 '11 at 02:36
  • @Kevin R: What about loading **two** script elements, where the second one loads from your server and contains your jQuery code? The first one is, of course, jQuery itself. – Richard Marskell - Drackir May 02 '11 at 02:54
  • Putting everything into one file DOES work. I tried using TWO script elements previously to load jQuery/jQuery-UI, but not to also load my page code. Let me try that... I suspect there will be problems ensuring which one loads first. – Kevin P. Rice May 02 '11 at 03:03
  • @Kevin R: Presumably the first one attached to the DOM would be the first executed but perhaps since your code is most likely going to be smaller than jQuery, it will be hit first. What about using the user-agent server side and controlling your included files that way? I know, it's not the best thing ever but if you're concerned about mobile browsers, it might be worth looking into. – Richard Marskell - Drackir May 02 '11 at 03:09
  • I may be all wet trying to defer jQuery loading in the first place, but it seems reasonable and it makes [Google PageSpeed](http://code.google.com/speed/page-speed/) happy. Chaining events via tylermwashburn's answer seems to be the way to load everything in order. Also, check out [JSL JavaScript Loader](http://www.andresvidal.com/jsl) which appears to be similar to what I'm trying to do. Much thx! – Kevin P. Rice May 02 '11 at 04:30
1

There is a simple trick which Google Analytics uses.

Preparation

1. In the head of your HTML add a tiny script

<script>
    window.jQuery_store = [];
    window.jQueryReady = function (fn) { jQuery_store.push(fn); }
</script>

The function jQueryReady will just save delegates into an array for future use.

2. Create a new JS script jquery-ready.js with next content:

// When jQuery is finaly ready
$(function() {
    // Replace previous implementation
    window.jQueryReady = function(fn) {
        // jQuery is loaded call immediately
        fn();
    }
    
    // Call all saved callbacks
    for (var i = 0; i < window.jQuery_store.length; ++i) {
        try {
            window.jQuery_store[i]();
        } catch (err) {
            console.log(err);
        }
    }
})

When this script is loaded, it will:

  • Wait until jQuery is safe to use
  • Will replace the function jQueryReady with a new one, which just calls delegate immediately (the jQuery is ready at the given time).
  • Iterate through functions saved from previous jQueryReady calls.

3. Put everything together Make jquery-ready.js load only after the jQuery is loaded. In your footer you will have:

<script defer src=".../jquery.min.js">
<script defer src=".../bootstrap.min.js">
... any other plugins for jQuery you probably need
<script defer src=".../jquery-ready.js">

This makes sure that the jquery-ready.js script will be executed only after the jQuery was executed.

Usage

You can now use jQueryReady function whenever you want.

jQueryReady(function() {
    // jQuery is safe to use here
    $("div.to-be-hidden").hide();
})
Seagull
  • 3,319
  • 2
  • 31
  • 37
  • Neat solution. I have not tried this one yet, but would there be a problem with plugins that waits for jQuery? – Reigel Gallarde Nov 03 '20 at 23:44
  • You should include jquery-ready.js after all plugins. In this case, jQueryReady will be called only when all plugins are loaded – Seagull Nov 04 '20 at 20:49
0

Appears that you just need <script defer> : http://www.w3schools.com/tags/att_script_defer.asp

c-smile
  • 26,734
  • 7
  • 59
  • 86
  • As per that link: "The defer attribute is only supported by Internet Explorer." The OP mentioned in a comment that they're using Chrome so I'm assuming this is a show-stopper. – Richard Marskell - Drackir May 02 '11 at 03:14
  • 8
    FYI, there's a movement to get people to stop recommending w3schools.com. http://w3fools.com/ – Dan May 02 '11 at 03:21
  • I'm creating public site that must provide wide cross-browser support. Also, it's not the deferral that is the problem--it's knowing when the deferred code (jQuery) is loaded and ready for functions to be called upon it. – Kevin P. Rice May 02 '11 at 03:22
0

Take a look jQuery.holdReady()

"Holds or releases the execution of jQuery's ready event." (jQuery 1.6+)

http://api.jquery.com/jQuery.holdReady/

mikeycgto
  • 3,368
  • 3
  • 36
  • 47
  • 1
    Thanks for that comment. It appears that holdReady() does not defer jQuery from loading, but just delays the Ready event. To clarify my question: Browsers spend a certain amount of time downloading and parsing all .js files before a page is rendered--mobile browsers are particularly slow to parse JS code. It is my desire to have the page render before .js files are even downloaded. Thus, the user sees the page quickly and can begin to digest the content while the .js files are downloaded and parsed. Hence, I am wishing to defer the actual download of .js files. – Kevin P. Rice May 29 '11 at 22:15
  • I see what you're saying. Some of the above scripts may help do that. Try uses Chrome's Audit tool to find out how to improve speed of your page – mikeycgto Jun 09 '11 at 17:33
0

I wanted to defer load jQuery on a WordPress site, so I couldn't practically update all the references using it. Instead wrote a small wrapper to queue the jQuery calls and call then whenever it's finally loaded. Stick it in the head, only 250 bytes or so, and it means jQuery can be deferred or async loaded without altering all the existing references. Made my load times much nicer.

My quick code may not work for all jQuery functions, but so far has worked with everything but one function call that I've tried. Normally I'm doing such custom stuff I don't make it available, but I thought I'd put this snippet online. Available here https://github.com/andrewtranter/jQuery_deferred_compat

Any
  • 31
  • 4
-3

Load all scripts at the end of html with http://labjs.com, it is 100% solution and I tested it many times against gtmetrix rules. example http://gtmetrix.com/reports/interactio.cz/jxomHSLV