If you look at todays web 2.0 sites you will realize there is often a heavy load on external JavaScript resources, CSS files and probably images. Above compressing and optimizing the files and merging multiple files (also background-images), there is not much room to further optimize the page loading process.
One problem of many modern sites is that they often provide optional functions for the user at the price of loading the main libraries all at once ending in a terrible site- and javascript-performance. I’ve already spoken about that once before and see more and more a good chance for web-applications based on Flex, or a real interface-language or perhaps Java. But we’re speaking about web-sites here not applications (anyway you could intermix them)!
Imagine a „passage-way“ or „pass-by“ page: How many of your users will use your “godly” fully featured search-window that you’ve implemented with Ext or the Prototype Window-Script and that runs inside the page? And what about overall JS and CSS footprint about 150KB? Really needed? And oh, it’s the only part of the website you’re using these scripts.
Maybe one of ten users will use your “godly” feature. The others all have to load the site, the slow JavaScript and you will pay bandwidth.
So, why don’t you just simply load the parts of the site when you need them? AJAX – it’s all about that but still people are loading tons of libraries on every single site!?
As you might guessed i worked on such a script today. It works pretty well in Firefox and Opera (not yet Safari and fucking MSIE), and i still have to come up with some issues and heavy testing (especially on older browser that probably don’t wanna let their DOM injected JavaScript or CSS; so a good wrapper for <script> is necessary). I just wonder why no one didn’t come up with that idea and a working script before. It saves me about 120KB on a product page. And 50KB on other sites. Now that’s ok?!
Here’s a little preview of the alpha sourcecode
/**
* Post-Load
* @version 0.1a
* @desc Why preload all your scripts? Dynamically them when they are needed!
* @author Markus Geiger 2007
* @package Postload
* @license MIT
* @url http://blog.evolution515.net
*/
PostloadJob = Class.create();
PostloadJob.prototype = {
totalFiles: 0, // holds number of total file to load
loadedFiles: 0, // holds number of loaded files
completeHandler: null, // function executed on complete loading
errorHandler: null, // function executed on error while loading
initialize: function(input, completeHandler) {
// Init the container for our files
Postload.htmlContainer = $(‘postload’);
if (!Postload.htmlContainer) {
var elem = document.createElement(‘div’);
elem.setAttribute(‘id’, ‘postload’);
document.body.appendChild(elem);
Postload.htmlContainer = $(‘postload’);
}
if (input)
return this.load(input, completeHandler);
},
load: function(input, completeHandler) {
if (completeHandler)
this.completeHandler = completeHandler;
if (typeof(input)==‘object’) {
this.totalFiles = input.length;
} else {
input = [input];
this.totalFiles = 1;
}
for (i=0;i<input.length;i++) {
var filename = input[i];
if (filename.indexOf(‘.js’)!=-1) {
this.loadJS(filename);
} else if (filename.indexOf(‘.css’)!=-1) {
this.loadCSS(filename);
} else {
return false;
}
}
},
complete: function() {
this.loadedFiles++;
if (this.loadedFiles!=this.totalFiles)
return;
if (this.completeHandler)
this.completeHandler();
},
loadJS: function(filename) {
var elem = document.createElement(’script’);
elem.setAttribute(’src’, filename);
Event.observe(elem, ‘load’, this.complete.bindAsEventListener(this));
Postload.htmlContainer.appendChild(elem);
},
loadCSS: function (filename) {
new Ajax.Request(
filename,
{
method: ‘get’,
onSuccess: this.completeCSS.bindAsEventListener(this)
}
);
},
completeCSS: function(transport) {
var elem = document.createElement(’style’);
elem.setAttribute(‘type’, ‘text/css’);
elem.innerHTML = transport.responseText;
Postload.htmlContainer.appendChild(elem);
this.complete();
}
}
Postload = new Object();
Postload.htmlContainer = null;
Postload.allFiles = new Array();
Postload.require = function(input, completeHandler) {
new PostloadJob(input, completeHandler);
}
Example usage
The syntax is very simple. Just use it like require from your PHP or Java language. The only difference is that it handles more than one file and calls a complete-handler when all files have finished loading. So chaining it into your applications should be very easy.
product._openComparisionWindow = function() {
Postload.require(
[
‘gz?lib/windows-js/javascripts/effects.js|lib/windows-js/javascripts/window.js’,
‘gz?lib/windows-js/themes/default.css|lib/windows-js/themes/alphacube.css’
],
product.openComparisionWindow
);}