The fastest way to load an image... to not load anything at all.

But as we really want to load an image, let's come with some solution that renders the page as soon as possible but ends up displaying the intended image.

By default, when a browser renders a webpage opens up to X connections per domain to fetch resources: CSS, external javascripts, and images. Usually between 4 and 6 for newer browsers.
It might render something, it might wait a bit then show you the page once it has some images... it depends on the browser and it's rendering engine. At home for example I usually get the full page at once, but with 3G or GPRS on my phone heavy-load pages I have to wait a lot to then see them partially render and notice the remainding images slowly loading.

The goal here is to achieve a quick first page load, because it is better to see an incomplete (but loading/filling) page instead of a white page that might give the impression of not even loading.

So, the first trick is hidden in my previous paragraphs: use a different subdomain to serve images. This way you can have up to 6 connections from your main domain, plus another 6 per subdomain. A typical images.xxxx or statics.xxxx will do the trick and look nice.

The second and third tricks are very well covered in one of the talks I gave in the past, so I will refer to them regarding how to cache statics in .NET and how to clean some unwanted headers from served content. Note that removing unwanted headers won't mean much speed gain so is not so important.

But still, if you want to build a typical slideshow with 200 images you will have to load all of them, no? Of course not! You only have to load the first one!
A typical user won't see all images, and even if they do so they can wait until you load the next image... So, next step can simply be ybuilding that: only load current image (first) and the rest as smaller thumbnails (after big current image).

We now have a slideshow that will probably load really fast on any home internet connection or tablet connected to a wifi. But if you hit it with hundreds of images, it will still take a bit to load, because of those hundreds of thumbnails loading in the page load.

So why not defer even them? Let's do this flow to apply the fifth trick:

  1. Load the page without any image nor thumbnail, but instead with 1x1 pixel gif placeholders.
  2. When the page is loaded, trigger loading an image as the current one.
  3. After triggering that, cycle through all thumbnail placeholders and trigger loading their proper images.

The JQuery code for doing this is really really trivial. You just need to play with some data-xxx attributes, and the resuls are really really noticeable.

I modified an existing slideshow to load thumbs with the method explained above (very useful if you have hundreds of images instead of just a bunch).

I halso ave a crappy private PHP photo uploader (nice for memes ;) with the typical "view all" button. Previously the browser would hang while loading hundreds of images, with this trick it loads in around 1 second, then takes its time to build the thumbnails, but always keeping the browser responsive to actions like scrolling down.

The advantages are clear and the effort quite minimal. Of course if you need to support non-javascript versions many things cannot be applied, but then you probably have other bigger worries than ajax or non-ajax loading of images.

Other improvements not implemented right now by me but typical for even faster loadings and better user experience:

  • Preloading of next images. It can be from one to X following images, so that when the user clicks it magically loads instantly.
  • Viewport-based image loading. Amazon and Instagram do this perfectly: They load with a minimal set of menu images, then dynamically load first the images you see on the screen, then either as you scroll down or when finished with visible ones, the remainder of off-screen images.
  • Batch loading. Instead of telling the browser to change 200 <img> src attributes, create a list/queue/whatever and some simple logic that retrieves batches of X elements (starting with the visible ones, of course), then when finished keep going until done with all tasks.

Posted by Kartones on 2012-12-18


Share via: Twitter Linkedin Google+ Facebook