Search code examples
cross-browserxmlhttprequestpreloadbrowser-cacheweb-optimization

How to preload JavaScript and CSS files in the background, to have them ready in the browser cache when the user goes to the main page?


I want to preload a JS file and a CSS file from the landing page to optimize the main site load, after the conversion in the landing. I was looking for information about this and finally tried to get this done using:

    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'jsUrl');
    xhr.send('');
    xhr = new XMLHttpRequest();
    xhr.open('GET', 'cssUrl');
    xhr.send('');

With Firefox this great, but with Chrome it seems that the XHR calls are cached in a different cache than the css and js files. We don´t use JQuery, the landing page must be lightweight (less load, more conversion rate).

Do you have any recommendation of another way to solve the original problem? (preload components)

Do you know how to make Chrome cache these requests?


Solution

  • This is a tested solution in a high volume site that works.

    First, to avoid a competition between the landing page resources and the preloaded resources for the bandwith you could delay the load with javascript:

    var prevOnLoad=window.onload;
    function onLoadPreloadComponents() {
        if(prevOnLoad) {
            try{
               prevOnLoad();
            }catch(err){
            }
        }
        preloadSiteComponents();
    }
    
    window.onload=onLoadPreloadComponents;
    

    This is not the way I solved this because in my use case a flash event (using the Flash to JS brigde) signals when the landing was finally loaded. But the previous code must works as well. When the load page event is fired by the browser this function will execute previous onLoad code and the preloading.

    I put an empty div cointainer where the iframe will be loaded.

    <div id="mainSiteComponentsContainer" style="display: none;">
    </div>
    

    And the function code is:

    function preloadSiteComponents() {
        try{
            document.getElementById('mainSiteComponentsContainer')
                .innerHTML=
                    "<iframe src=\"http://www-components.renxo-cdn.net/preload-site-components-data-url-scheme-version-1.2.84-css-1.0.53.html\" frameborder=\"no\" height=\"0px\" width=\"0px\"></iframe>";
        }catch(err) {
        }
    }
    

    As you could see, the link url to iframe is dynamic, it changes between differents plataform versions (different deployments) to avoid unwanted browser cache with a new deployments.

    The HTML that will be in the iframe could be something like this (for example):

    <html class=" gecko win js" xmlns="http://www.w3.org/1999/xhtml">
        <head>
            <meta content="noindex,nofollow" name="robots">
            <script src="http://www-components.renxo-cdn.net/scripts/lib-1.2.84.js" type="text/javascript">
            <link href="http://www-components.renxo-cdn.net/styles/skin-data-url-scheme-1.0.53.css" media="all" type="text/css" rel="stylesheet">
        </head>
        <body> </body>
    </html>
    

    Here you could see the links to the components that I want to preload. Finally, the div cointainer will have the iframe. After the onLoad event:

    <div id="mainSiteComponentsContainer" style="display: none;">
        <iframe width="0px" height="0px" frameborder="no" src="http://www-components.renxo-cdn.net/preload-site-components-data-url-scheme-version-1.2.84-css-1.0.53.html">
            <html class=" gecko win js" xmlns="http://www.w3.org/1999/xhtml">
                <head>
                    <meta content="noindex,nofollow" name="robots">
                    <script src="http://www-components.renxo-cdn.net/scripts/lib-1.2.84.js" type="text/javascript">
                    <link href="http://www-components.renxo-cdn.net/styles/skin-data-url-scheme-1.0.53.css" media="all" type="text/css" rel="stylesheet">
                </head>
                <body> </body>
            </html>
        </iframe>
    </div>
    

    You could see the working solution here.

    Use Firebug to see the delayed load of this components.