bloginfo('name');

bloginfo('description');

Post-load your JavaScript and CSS files!

Juli 25th, 2007 by Blu:RayNe

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
    );}
Filed under Browser, CSS, JavaScript having

Leave a Comment

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.