4

I have a page which contains a dozen of big images:

<div id="gallery">
  <img src="1.png" alt="" />
  <img src="2.png" alt="" />
  ...
</div>

Due to images' size, parallel downloading causes too long delay before anything shows.

Question: how to load images sequentially, so that 2.png only starts loading after 1.png has been fully loaded and displayed?

  • I don't want lazy loading (unless you know of a plugin which will always load images strictly in the same sequence, regardless of the current viewport)

  • This solution:Loading images sequentially doesn't work for me in latest Chrome, Firefox, IE. It will load all images at once, and then show them

  • The plugin suggested in this answer https://stackoverflow.com/a/25774333/525445 is somewhat functional but it makes 2, 3 or sometimes more requests at once, so not doing what it's supposed to

  • Then there's this plugin, also proposed in some answer: http://imagesloaded.desandro.com/ It's meant for something else though - to let you know when all images are loaded, which it does well. So I tried to put it to use like this:

    var $gallery = $("#gallery");
    $gallery.imagesLoaded( function() { $gallery.append(''); console.log("Image loaded"); }); $gallery.append('');

The idea here was - to dynamically add images one by one, on imagesLoaded event. However, it gets triggered only for the first image (although it's dynamically added as well), and for the second it doesn't. So the above code causes both images to show, but only 1 console.log() notification

Any suggestions appreciated.

Community
  • 1
  • 1
CodeVirtuoso
  • 6,318
  • 12
  • 46
  • 62

2 Answers2

7

Basically you want to start with an empty container. The path to the images would be contained in a Javascript array, and then brought in one after another using a off-screen element loading methodology. Code:

<div id="gallery"></div>
  
<script>
var images = [
    { src: '1.png', alt: 'I am the first image' },
    { src: '2.png', alt: 'Second image' }
];

function loadImageSequentially(imagesArray, appendTo, loadImageAtIndex) {
    if (!loadImageAtIndex) loadImageAtIndex = 0; // assume first loading if not provided.
    if (!imagesArray[loadImageAtIndex]) return;

    var img = new Image();

    // attach listeners first
    img.onload = function() {
        appendTo.appendChild(img);
        loadImageSequentially(imagesArray, appendTo, loadImageAtIndex + 1);
    }
    img.onerror = function() {
        // remove listeners
        img.onload = img.onerror = null;
        img.src = 'error.png'; // if you have a placeholder error png to display, put it here.

        // life goes on...
        appendTo.appendChild(img); 
        loadImageSequentially(imagesArray, appendTo, loadImageAtIndex + 1);     
    }

    // assign attributes, which will start the loading.
    img.src = imagesArray[loadImageAtIndex].src;
    img.alt = imagesArray[loadImageAtIndex].alt;
}

// now run it.
var appendTo = document.getElementById('gallery')
loadImageSequentially(images, appendTo);
</script>

This example can be modularised and made better. But is left at such for the purpose of illustration.

Calvintwr
  • 8,308
  • 5
  • 28
  • 42
  • I'm very curious to understand this code could you please explain. My doubt is, when you're calling a function, you're passing only 2 params but function actually requires 3 params. did 3rd parameter is not required. I didn't understand ? – Raj May 03 '15 at 18:45
  • 1
    He makes the 3rd parameter optional - so if you don't provide it, it's set to 0 in the first line of the function. – CodeVirtuoso May 03 '15 at 20:02
  • 1
    @Calvintwr +1 but one question , so its the below lines :` img.src = imagesArray[loadImageAtIndex].src; img.alt = imagesArray[loadImageAtIndex].alt;` that are actually triggering the event handlers ?? Thanks – Alexander Solonik May 05 '15 at 22:03
  • it's `img.src` that is triggering the `onload` event handler. – Calvintwr May 06 '15 at 06:56
  • 1
    If the onerror hits then if there is no error.png then it goes on forever. I inserted img.onerror= null; in the img.onerror function to stop it recurring. – JoePythonKing Dec 29 '21 at 10:40
  • @JoePythonKing your comments incorporated. thanks much. – Calvintwr Dec 29 '21 at 19:08
0

Try using lazy load on page scroll. It starts loading of images when user scrolls to that, so images are not loaded parallelly, instead it will be sequential ine after other in a way.

Luke P. Issac
  • 1,471
  • 15
  • 32
  • Lazy load will start loading all images in the viewport. So if there's more than 1 image in the viewport, they won't be loaded 1 by 1. Same if user is not starting to view page from the top, or scrolls down faster than the images load. – CodeVirtuoso May 04 '15 at 08:59