joedborg
joedborg

Reputation: 18353

Speed up iteration over array javascript / jquery

function pop(index,value) {
    if (typeof thumbnail_list == 'undefined') {
         thumbnail_list = {};
    }
    thumbnail_list[index] = value;


}

function render() {
    $.each(thumbnail_list, function(i, v) {
        $("#"+i).attr("src",v);
    });
}

This is my code, what happens is a list of thumbnail paths (value) are fed into pop with the img id (index). There around 500 thumbnails fed. When render is executed, it adds the src to the img, showing the image. This is taking a while to populate. The thumbs are only 100 x 50px and 5kb. Is it just the shear volume, or is my code slowing things down?

Upvotes: 1

Views: 176

Answers (3)

jfriend00
jfriend00

Reputation: 707436

I rather doubt your performance problem is the pure javascript execution time of your loop. It is much, much more likely an issue of how long it takes a browser to load 500 separate images, even if they are small.

It takes a meaningful amount of time for the browser to fetch 500 images over the internet. Due to connection management, it will only request N at a time and have to wait for images to finish loading before requesting more. This serialization of the loading can really add up. As such, these are some ways to speed up the loading:

  1. Use Sprites where you can load one image and display many thumbs from different parts of it. This is the most efficient way to display lots of small images. This requires combining many images into one and then restructuring your display and load logic to use the sprites. Search for CSS sprites on Google to see how this is done.
  2. Preload the 500 images. If the URLs are known ahead of time, you can preload the images into an array of Image objects using javascript. Then, when they are added to the DOM, they will all come from the browser cache rather than over the network.
  3. Restructure your display logic to load thumbnails on demand rather than load them all at once. Since I'm guessing that all 500 are not displayed on screen at once, the ones that are scrolled off the screen can be loaded upon demand later when their area of the screen scrolls into view. There are libraries that help with such on-demand loading.

The most efficient and fast method would probably be a combination of sprites and preloading.

Upvotes: 3

vzwick
vzwick

Reputation: 11044

As a minor optimisation, since you don't seem to mind cluttering the global namespace anyways, I'd suggest this:

var thumbnail_list = {};

function pop(index,value) {
    /* one less check to run, yay? */
    thumbnail_list[index] = value;
}

As for your render() function - you could do the whole thing with vanilla JS instead of jQuery. Not quite sure about the real-world performance impact, though:

function render() {
    for (index in thumbnail_list) {
        document.getElementById(index).src = thumbnail_list[index];
    }
}

Upvotes: 0

endyourif
endyourif

Reputation: 2202

It looks like you are doing two loops, one to first populate thumbnail_list and then to create the image. You could probably merge it all into the pop function:

function pop(index,value) {
    if (typeof thumbnail_list == 'undefined') {
        thumbnail_list = {};
    }
    thumbnail_list[index] = value;

    $("#"+index).attr("src",value);
}

Upvotes: 0

Related Questions