views:

150

answers:

2

I'm building a website with around 250-300 thumbnails on a single page, contained in 5 different divs which can each be scrolled horizontally.
During the loading stage, however, I need to be able to click on a thumbnail and load the full-res picture in the lightbox.

I've looked at Jason Buntings answer in How to display loading status with preloader and multiple images? which gets me there half the way: it works in IE but not in FF where it doesn't load the lightbox-image until all the thumbnails are loaded.

So I rolled my own code building on the same concept: it works but is unstable (random hangs) and uses tons of memory:

function doLoadThumbnails(queue) {
  if (!queue.isEmpty()) {
 if (connManager.AcquireConnection()) {
  var imageLink = queue.dequeue();
  var loader = new Image();
  loader.onload = function() {
   imageLink.firstChild.src = imageLink.href;
   connManager.ReleaseConnection();
  }
  loader.src = imageLink.href;

  doLoadThumbnails(queue);
 } else {
  connManager.getEventObject().bind('connReleased', function(e) {
   window.setTimeout(function() {
    doLoadThumbnails(queue);
   }, 50);
   connManager.getEventObject().unbind('connReleased', arguments.callee);
  });
 }
  }
}

ConnectionManager looks like this:

function ConnectionManager() {
  var eventObject = $('<span id="ConnectionManager"></span>').appendTo("body");
  var activeConnections = 0;
  var maxConnections = 5;

  this.getEventObject = function() {
    return eventObject;
  }

  this.isConnectionAvailable = function() {
 return activeConnections < maxConnections;
  }

  this.AcquireConnection = function() {
 if (activeConnections < maxConnections) {
  activeConnections++;
  return true;
 } else {
  return false;
 }
  }

  this.ReleaseConnection = function() {
 activeConnections--;
 eventObject.trigger('connReleased');
  }
}

Is this a basically sound concept or am I way off? Do you know any better/simpler method to do this?

A: 

One suggestion: I would "default" max connections to 2 - its the most allowed in the HTTP/1.1 spec to the same domain anyway - so most browsers wont load more than 2 images at a time.

gnarf
I get a 2% improvement (profiled with firebug) with 5 connections over 2, it seems to be the sweetspot in regards to maximising throughput within the browsers hard-limit. But admittedly, I haven't tried it over a high-latency link yet.
Michael Wagner
My reason for the suggestion is when you need to force another image into the load chain (click on it) - its better to only have to wait for the two its working on to finish than the other 3 it has been waiting to download. I think the performance increase you are seeing may be purely based on the amount of time it takes to queue the next request not being used to download an image, so - touche :)
gnarf
Hehe, of course I forgot about the big image and its queue position... Thanks.
Michael Wagner
A: 

Is this a favorable way to do this, or are there better and faster possibilities?

One of the biggest speed improvements you will get is reducing the overall number of requests that you are making.

If you've got access to an image processing library on the server, it might be worth considering writing a script to render the all the thumbnails for each div into one large contact sheet image.

You could use an image map to figure out which full-res picture to display when the user clicks on the contact sheet (or you could possibly use a CSS sprite technique to render the correct thumbnail as a background on your link to the full-res picture, if you wanted to highlight the border of the thumbnail on mouseover).

HTH :^)

Gus Gollings