Click here to Skip to main content
15,890,579 members
Articles / All Topics

Preloading Resources - The Right Way (for me)

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
12 Apr 2014CPOL4 min read 12.1K  
Preloading resources - the right way (for me)


Looking through my 'client side performance glasses' when browsing the web, I see that many sites spend too much time downloading resources, mostly on the homepage, but sometimes the main bulk is on subsequent pages as well.

Starting to Optimize

When trying to optimize your page, you might think that it's most important that your landing page is the fastest since it defines your users' first impression. So what do you do? You probably cut down on all the js and css resources you can and leave only what's definitely required for your landing page. You minimize those and then you're left with one file each. You might even be putting the js at the end of the body so it doesn't block the browser from rendering the page, and you're set!

But There's Still A Problem

Now, your users go onto the next page, probably an inner page of your site, and this one is filled with much more content. On this page, you use some jquery plugins and other frameworks you found useful and probably saved yourself hours of JavaScript coding, but your users are paying the price...

My Suggestion

I ran into this same exact problem a few times in the past, and the best way I found of solving this was to preload the resources on the homepage. I can do this after 'page load' so it doesn't block the homepage from rendering, and while the user is looking at the homepage, a little extra time is spent in the background downloading resources they'll probably need on the next pages they browse.

How Do We Do This?

Well, there are several techniques, but before choosing the right one, let's take a look at the requirements/constraints we have.

  • We want to download js/css files in a non-blocking way
  • Trigger the download ourselves so we can defer it to after 'page load'
  • Download the resources in a way that won't execute them (CSS and JS) (This is really important and the reason we can't just dynamically create a '<script/>' tag and append it to the '<head/>' tag!)
  • Make sure they stay in the browser's cache (this is the whole point!)
  • Work with resources that are stored on secure servers (https). This is important since I would like it to preload resources from my secured registration/login page too if I can.
  • Work with resources on a different domain. This is very important since all of my resources are hosted on an external CDN server with a different subdomain.

The Different Techniques Are (I have tested all of these, and these are my notes)

  1. Creating an iframe and appending the script/stylesheet file inside it:
    JavaScript
    var iframe = document.createElement('iframe');
    iframe.setAttribute("width", "0");
    iframe.setAttribute("height", "0");
    iframe.setAttribute("frameborder", "0");
    iframe.setAttribute("name", "preload");
    iframe.id = "preload";
    iframe.src = "about:blank";
    document.body.appendChild(iframe);
    
    // gymnastics to get reference to the iframe document
    iframe = document.all ? document.all.preload.contentWindow : window.frames.preload;
    var doc = iframe.document;
    doc.open();
    doc.writeln("<html><body></body></html>");
    doc.close();
    
    var iFrameAddFile = function(filename) {
        var css = doc.createElement('link');
        css.type = 'text/css';
        css.rel = 'stylesheet';
        css.href = filename;
        doc.body.appendChild(css);
    }
        
    iFrameAddFile('http://ourFileName.js');

    This works on Chrome and FF, but on some versions of Internet Explorer it wouldn't cache the secure resources (https).
    So, close, but no cigar here (at least, fully).

  2. Creating a JavaScript Image object:
    JavaScript
    new Image().src = 'http://myResourceFile.js';

    This only works properly on Chrome. On FireFox and Internet Explorer, it would either not download the secure resources or download them but without caching.

  3. Building an <object/> tag with file in data attribute:
    JavaScript
    var createObjectTag = function(filename) {
        var o = document.createElement('object');
        o.data = filename;
    
        // IE stuff, otherwise 0x0 is OK
        if (isIE) {
            o.width = 1;
            o.height = 1;
            o.style.visibility = "hidden";
            o.type = "text/plain";
        }
        else {
            o.width  = 0;
            o.height = 0;
        }
    
        document.body.appendChild(o);
    }
       
    createObjectTag('http://myResourceFile.js');

    This worked nicely on Chrome and FF, but not on some versions of Internet Explorer.

  4. XMLHttpRequest a.k.a. Ajax:
    JavaScript
    var ajaxRequest = function(filename) {
        var xhr = new XMLHttpRequest();
        xhr.open('GET', filename);
        xhr.send('');
    }
    
    ajaxRequest('http://myResourceFile.js');

    This technique won't work with files on a different domain, so I immediately dropped this.

  5. Creating a 'prefetch' tag:
    JavaScript
    var prefetchTag = function(filename) {
        var link = document.createElement('link');
        link.href = filename;
        link.rel = "prefetch";
        document.getElementsByTagName('head')[0].appendChild(link);
    }
    
    prefetchTag('http://myResourceFile.js');
  6. 'script' tag with invalid 'type' attribute:
    JavaScript
    // creates a script tag with an invalid type, like 'script/cache'
    // I realized this technique is used by LabJS for some browsers
    var invalidScript = function(filename) {
        var s = document.createElement('script');
        s.src = filename;
        s.type = 'script/cache';
        document.getElementsByTagName('head')[0].appendChild(s);
    }
    
    invalidScript('http://myJsResource.js');

    This barely worked in any browser properly. It would download the resources, but wouldn't cache them for the next request.

Conclusion

So, first I must say that given all the constraints that I have, this is more complicated than I thought would be at first.

Some of the techniques worked well on all of the browsers for non-secured resources (non SSL) but only on some browsers for secured resources. In my specific case, I just decided to go with one of those, and figure that some users will not have cached resources that are for SSL pages (these are a minority in my case).

But, I guess that given your circumstances, you might choose a different technique. I had quite a few constraints that I'm sure not everyone has. Another thing worth mentioning is that I didn't test Safari on any technique. Again, this was less interesting for me in my case.

I also didn't think about solving this problem on mobile devices yet. Since mobile bandwidth is also usually much slower, I might tackle this problem differently for mobile devices...

This article was originally posted at http://www.debuggerstepthrough.com/feeds/posts/default

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Israel Israel
Started programming e-commerce sites with PHP & MySQL at the age of 14. Worked for me well for about 5 years.

Transfered to C# & asp.net, while serving in the IDF.
Worked on the 'Core Performance' Team at ShopYourWay.com (Sears Israel)
Currently working at Logz.io

Check out my blog!
or my twitter

Comments and Discussions

 
-- There are no messages in this forum --