2

Because my client's page has tons of Javascript, the image carousel I added on top for mobile version takes forever to render on smartphones. I want to load carousel images then carousel required files (jQuery, carousel JS files, carousell CSS files) before anything else including JS, CSS, etc.

Is it possible, and if so how to do it?

drake035
  • 3,955
  • 41
  • 119
  • 229

6 Answers6

6

Try this way:
Load Image from javascript

if you can load the image first and then just use it anywhere, they will load as soon as the javascript loads and you have to put this javascript before everything else (as you asked)

And, to load JS first, you just need to put them as the first, for example:

JQuery must be loaded BEFORE Bootstrap otherwise it won't work.

Community
  • 1
  • 1
Simego
  • 431
  • 5
  • 16
2

You can create a javascript method which checks all images whether they are loaded or not.

var preLoadImages = function (arr) {
    var newImages = [], // temparary variable containing loaded images
        loadedImagesCount = 0; // 
    var postAction = function () {};
    var arr = (typeof arr != "object") ? [arr] : arr; // if a single image is sent, convert it into array

    function imageLoadPost() {
        loadedImagesCount++;
        if (loadedImagesCount == arr.length) {
            postAction(newImages) // postAction method
        }
    }
    for (var i = 0; i < arr.length; i++) {
        newImages[i] = new Image();
        newImages[i].src = arr[i];
        newImages[i].onload = function () { // call imageLoadPost when image is loaded
            imageLoadPost();
        }
        newImages[i].onerror = function () { // call imageLoadPost when error occurred because its also an success event which already checked whether mage is available or not
            imageLoadPost();
        }
    }
    return { //return blank object with done() method
        done: function (f) {
            postAction = f || postAction // user defined callback method to be called when all images are loaded
        }
    }
}

// image array contains all images which you want to preload - currently having sample images
var imgArr = ['http://doc.jsfiddle.net/_images/jsfiddle-logo-thumb.png', 'http://doc.jsfiddle.net/_images/jsfiddle-desktop-thumbnail-a.png'];
preLoadImages(imgArr).done(function (imgArr) {
    alert('all images loaded');
    // call your carousel here
})

In done method, you can create your carousel. You need to add this method in a file and put that in top of the stack where you load your javascript files.

JSFiddle link

Mohit Pandey
  • 3,679
  • 7
  • 26
  • 38
1

I have an idea:

  1. load jQuery first. [ADDED]

  2. don't include the js and css files you want to lazy load.

  3. write a javascript array (in order) for the js and css you want to lazy load (see below).

  4. in the html identify with attribute all the you want to load later.(just use an arbitrary attr)

    <img src="_images/loadMeFirst.jpg" />
    
    <img src="_images/1x1.png" lazyLoad="_images/loadMeLater.jpg" />
    
  5. on document complete, go through all lazyLoad images, re-assign src attr with lazyload src.

  6. on dom ready, add an arbitrary window event listener, perhaps "LoadNextScript", which will inject the next from the array.

  7. at the end of each injected js file, add a line to raise the (arbitrary) "LoadNextScript" event. (Note: You can skip this functionality if you are ok with the scripts loading asynchronously, and just load them like the css files.)

    $(window).trigger( "LoadNextScript" );
    
  8. on document complete, raise the first (arbitrary) "LoadNextScript" event.

  9. on document complete, inject the css files from the css array.

JS:

window.lazyLoad = {
    jsNextIndex: 0,
    jsFiles: ["_js/file1.js", "_js/file2.js"],
    cssFiles: ["_css/file1.css", "_css/file2.css"],
    loadLazyImages: function () {
        $('img[lazyLoad]').each(function () {
            var $img = $(this);
            $img.attr('src', $img.attr('lazyLoad'));
        });
    },
    loadNextScript: function () {
        // must add
        // $(window).trigger( "LoadNextScript" );
        // at the end of each js file to be lazy loaded.
        var sScriptSrc = window.lazyLoad.jsFiles[window.lazyLoad.jsNextIndex] || false;
        if (sScriptSrc) {
            $('<script type="text/javascript" src="' + sScriptSrc + '" />').appendTo($('body'));
        }
        window.lazyLoad.jsNextIndex++;
    },
    loadAllCss: function () {
        var $head = $('head');
        for (var i = 0; i < window.lazyLoad.cssFiles.length; i++) {
            $('<link rel="stylesheet" href="' + window.lazyLoad.cssFiles[i] + '" type="text/css" media="screen" />');
        }
    },
    domReady: function () {
        // wire Lazy Script Event
        $(window).bind('LoadNextScript', window.lazyLoad.loadNextScript);

        // on window load complete (all non-lazy images)
        $(window).load(function () {
            // load all lazy images
            window.lazyLoad.loadLazyImages();
            // load the css
            window.lazyLoad.loadAllCss();
            // load/trigger the first script
            window.lazyLoad.loadNextScript();
        });
    }
};

jQuery(function ($) {
    // init lazy loader
    window.lazyLoad.domReady();
});
Levi Beckman
  • 533
  • 3
  • 8
  • You only need to add the 'LoadNextScript' functionality if you need them to load in order. Otherwise, exclude that and the scripts will run async. – Levi Beckman Feb 18 '14 at 21:20
1

Use <script async="true" src="zyx.js" /> and move your JS to the bottom of the page.

Chris Gunawardena
  • 6,246
  • 1
  • 29
  • 45
0

Assuming you are having to work around the fact that your clients JS is loaded first without implementing a more elegant solution - you could always go for the simple solution and add the async attribute to the slow script.

Here's an example

If you are not able to do that - it would be good to know your limitations due to the existing code base (can you move the script tag for example).

James Gorrie
  • 351
  • 2
  • 6
0

If you are doing an ajax load of all your images in carousel then consider using $.post which is async in nature.

Java_User
  • 1,303
  • 3
  • 27
  • 38