1

My objective here is to load scripts asynchronously when the browser supports defer or async.
If the browser supports neither I don't care about asynchronous loading (not my bad).
I want to make sure that any script is only executed when the prerequisites for it are fulfilled e.g. jQuery loaded. I want to load my scripts while other scripts are being loaded (only if the browser supports defer or async).

I want to do this using only the browsers' API. I don't want the browser to load any reliable (or not) scripts that do that for me no matter how small they are.

This must work with IE8+, Gecko v.1.9.1+ (e.g. firefox 3.5.* or firefox 9.0+), webkit (e.g. chrome), presto (e.g. Opera). For the ones I didn't mention the version, I mean the latest stable version.

If possible I don't want any non easy scripts. I just need something simple to do this job. This means:
If possible, I don't want stuff like AJAX calls or fancy Objects with some methods to do some workarounds like I've seen in other pages. Those are to force async loading of the script in browsers that do not support async or defer

I repeat: I don't need any fancy things to make a script asynchronous. If the browser does not support defer or async I don't care. I just care is that the script is loaded so that each part is executed after its prerequisites are met and use async or defer if the browser supports it.

brunoais
  • 6,258
  • 8
  • 39
  • 59
  • 2
    Good luck in re-inventing the wheel – Andreas Jan 30 '12 at 10:05
  • For you to say that, that only means that you don't know what I'm requesting here. I don't want the weel. I just want to make sure that everything runs in the correct order. – brunoais Jan 30 '12 at 11:58
  • The main reason is because I don't want to have hanging just to download the script that will solve hanging when the browser does support defering or async – brunoais Jan 30 '12 at 12:04

1 Answers1

1

First, using a library such as jQuery makes this whole process infinitely easier, and reliable across browsers. It may increase the download size of your pages (by a very small amount) but the speed gained by efficient script loading/executing will nearly always outweigh that.

Regarding script async and defer attributes:

  1. async="async": on a script tag is not supported at all by IE8/9, script executes immediately (which is ok according to your question).

  2. defer="defer": on a script tag will begin loading after everything in the order the defer scripts appear in the HTML, prior to DOM Ready. BUT, on Firefox, scripts will often execute AFTER dom ready. This difference makes defer unreliable as a means of ensuring that scripts are loaded before executing functions after dom ready.

General Guidelines when not using jQuery:

  1. If a script has downstream dependancies you have to place it as a standard script tag at the end of the body tag and have your inline tags all execute after document ready. Otherwise there is no guarantee that the script will be executed prior to the execution of the dependencies. Firefox is the main issue here, a "defer" script may not have finished even after DOM ready.

  2. If a script has no downstream dependnacies, then place it at the end of the body tag, and use async="async" attribute on the script tag. IE will render it immediately and the others will render it when they receive it.

General Guidelines when using jQuery:

  1. Place only jQuery in your <head>.

  2. Execute all other scripts as $.getScript().

  3. If a script needs to execute ASAP (such as analytics) use a $.getScript at the top of the body (this will be a non-blocking request, but will process as soon as the client receives the file).

  4. If a script can wait till DOM ready, wrap the $.getScript() call in $(function() {});

  5. If a script has many downstream dependancies, have each one register itself to the callback function for a specific script.

  $(function() { 
    $.getScript("script.js", function() {
      for(var i = 0; i < myCallbacks.length;i++) {
        myCallbacks[i]();
      }
    });
  });
Owen Allen
  • 11,348
  • 9
  • 51
  • 63
  • Surprisingly, the jQuery's getScript() turns to be a fail. Even though it is able to obtain the scripts, it is slower in the current most used browsers (FF 3.6, FF11, IE8, IE9...) than simply placing the tags at the bottom of the page. Besides, getScript() relies on caching which may be turned off in the browser (if that happens, 2x download happens) – brunoais Apr 20 '12 at 06:38
  • I don't see any evidence a script is loaded twice, view this test fiddle http://jsfiddle.net/nKsGP/, I setup the webserver to sleep for 5s on request (to simulate a slow script). If it was loading twice, it would take 10seconds, it does not. In addition, I don't quite see how it could be "slower"... loading a script is loading a script. The primary reason to use $.getScript() versus normal tags at the bottom, is that dom ready events can still fire, rather than having to wait for all scripts to load, and if one times out, too bad. – Owen Allen Apr 20 '12 at 08:27
  • Did you turn cache off? If you didn't, then your test isn't valid to prove what I have written. – brunoais Apr 20 '12 at 20:59
  • I did turn caching off, and you could test it yourself if you go to the fiddle I linked. I'm pretty certain the criticism you are throwing out there is relating to head.js, not jQuery. From http://headjs.com - `This trick is used on Chrome, Safari and IE. Without caching enabled a file will be loaded twice on the initial load.`. – Owen Allen Apr 21 '12 at 00:18
  • Analytics doesn't have to be loaded ASAP at all. Quite the contrary, this is the kind of script that can load at the latest time possible without affecting the user experience. It won't affect your stats enough for it to be a problem. – Bite code May 05 '12 at 13:44