window.onload Faster is Better!
First Check out Dean Edwards Article on window.onload. Dean is a smart guy, and really kicked out something nice with his window.onload fix, or rather a pre-emptive check. While Dean may have inspired this idea, it was the lack of support for a few things that I was really after. Thanks to a buddy of mine Robert Evans and a chat over lunch about how great it would be to be able to include the javascript libraries you wanted within a javascript file and not in the HTML the include.js library was born. Then as I was building this thing out, I realized that I could actually load my javascript files faster if I used asynchronous XMLHTTPRequests (98% of browsers support this) and extend it just a little further to have load functions as soon as its done and actually get all of the goodness that Dean’s solution offers and more.
Let’s go over how it works…
- Loads all of your javascript files via an include.files() method which uses asynchronous XMLHTTPRequests essentially bypassing the 2 files at a time browser limit.
- Accomplishes the same thing as Dean’s method allowing the javascript to immediately available instead of waiting for the page to load so those darn kute kitties can get to the litter box fast.
- Uses no Event Handlers or browser specific checks.
- Allows you to pass functions you want executed after the load is complete.
- On average performs 50% faster than Dean’s method.
So before we get to talking about the details, let see it in action.
- The Standard Way
- The Dean Way
- The Proposed Way
- The Standard Way w/Image
- The Dean Way w/Image
- The Proposed Way w/Image
Note: Don’t mean to label the other way the Dean way, just thought it would be easy to recognize.
So I would suggest using the Load Time Analyzer Add-on for Firefox to see the difference and using the ones without the images as the image loading is dependent on NASA. Basically we take in the list of files, loading them up all at the same time, and dropping the contents into a script tag that we create. Then we execute all the functions you want to run after the libraries are loaded. Now the first question that your probably thinking it, what about the cache, since these are loaded every time dynamically and into the page they aren’t cached. Well oddly enough they are. With XMLHTTPRequests if the method used is a GET Method unless the headers of the requesting file say otherwise the cached version is grabbed after the request is sent (on readystate == 1 in IE for example). Which works well for us and still gives us that 50% goodness.
So how do we use it?
- First download include.js
- Include the file in your page.
- Include files via the include.files() method
include.files(file1, file2, file3, file4);
- Add any onload functions via the include.onLoad() method
include.onLoad(function1, function(){…}, function2);
- Drink a beer and enjoy!
Ok, so all that being said this is a new idea and I am hoping you guys will throw your thoughts and ideas, maybe this can be a really good thing, so far it looks like it. Please share…
May 10th 2007
Just mind you tough that recursive xmlhttprequest handling or script-tag inclusion does not work. (as in dependency resolution). You might get around that with timeout handlers or hackery, but I’ll bet that works even on less browsers.
Me, I found a simple way. I coded a preprocessor that processes // include directives on the server. Works fine, is ultra fast, and doesn’t introduce all kinds of new headaches (or requests for that matter).
May 10th 2007
I see what you are saying, however with this method you wouldn’t really want to put the includes at the top and have a bunch of code below it, the load time would increase and would not be handled by this library. However I think I will add the ability to wait for the include to finish so this method will work and I think I can do it without setTimeout.
Thanks.
May 14th 2007
Hi Kevin,
I thin you’re totally missing Dean’s point.
Dean’s solution offers an onReady callback which allows JavaScript to access the DOM as soon as the DOM is ready (i.e. before window.onload).
I fail to see how your solution offers an alternative to Dean’s in that aspect.
Further more, the libs fail to load in Safari with your script. The only known solution to this second issue is to use document.write, check out the source code of scriptaculous.js for more details on how to do this (and yes, it is ugly, and won’t work if you serve your page as application/xml).
May 15th 2007
Tobie you are absolutely right as far as the solution, but no I did not miss Dean’s point, my initial tests were showing something promising in that regard and upon further more intensive tests the latter has become apparent. Then again thats why I was looking for input
However I believe a combination of this method AND Deans method can result in an improvement. Loading via the script tag is just wrong on so many levels. For example TinyMCE does this and with my recent tests I can load ALL of TinyMCE’s dependencies in 1.6 seconds as opposed to the standard 15-20 seconds.
In regards to safari its not working because the DOM is not ready, this is where I see Dean’s method now coming in. Please keep the feedback coming, I still think there is promise here and will continue to play with it. I will have a new version soon with Deans method integrated into it.
May 15th 2007
Kevin,
I might be wrong, but I believe the fastest solution regarding loading times is the one now built in edge rails: loading a unique JavaScript file, containing all of your libraries (Prototype, script.aculo.us, etc).
For maximum performance, this file should be gzipped.
May 15th 2007
This is a good solution and one that I employ quite often whether its rails or a php file to combine all of them and gzip them. Though most people don’t use/do things like this and aside from that you still have to wait for the resources to load in order where is with this solution you can do some ‘threading’ and get around browser limitations with 2 concurrent downloads at a time. Another good solution for rails would be the new asset loader as talked about on Chad Fowlers Blog.
May 23rd 2007
hi Kevin, I was wondering how can I load tinyMCE using this method, coz i always got “tinyMCE.baseURL has no properties” error if I load tiny_mce.js using include.files() function.
May 30th 2007
hello,
i am noob for this can you write the complete cod for the include files and onload ?
Feb 17th 2008
Hi Kevin,
First, the Accordion is killer. Nice work.
I tried using it with the latest version of proto and scriptaculous and it doesn’t work. Am I dong something wrong, or is it simply not compatible?
Thanks,
Bo
Feb 26th 2008
Your comment contains very useful information about all thank you fransızca tercüman
Jun 25th 2008
This concept sounds very intriguing indeed however when I click all the links are dead so I cannot try it or see the code.