How I deal with deferred image loading in Javascript

08 June 2012   3 comments   Web development, JavaScript

Mind that age!

This blog post is 8 years old! Most likely, its content is outdated. Especially if it's technical.

First of all, this technique is only really applicable to apps where there's only one big HTML template which is then shuffles, part hidden and part visible thanks to lots of Javascript. Those familiar with jQuery Mobile will have seen this.

On Around The World there are a lot of images. Majority of them you don't need to see immediately because only one screen is loaded at the time. The page structure looks like this:

<div class="section" id="page1">
  <h2>Page 1</h2>
  <img src="section-icon1.png">
<div class="section" id="page2" style="display:none">
  <h2>Page 2</h2>
  <img src="section-icon2.png">
<div class="section" id="page3" style="display:none">
  <h2>Page 3</h2>
  <img src="section-icon3.png">

So, if you load that you'll notice that your browser will download "section-icon1.png", "section-icon2.png" and "section-icon3.png" even though two of the images are not going to be displayed. Good for pre-loading the images when they're later needed but bad for the user experience since the browser will be busy downloading images rather than displaying the first visible section.

This is how I solve this; first I change the HTML to be this:

<div class="section" id="page1">
  <h2>Page 1</h2>
  <img src="." data-src="section-icon1.png" class="deferred">
<div class="section" id="page2" style="display:none">
  <h2>Page 2</h2>
  <img src="." data-src="section-icon2.png" class="deferred">
<div class="section" id="page3" style="display:none">
  <h2>Page 3</h2>
  <img src="." data-src="section-icon3.png" class="deferred">

And now for the magic that turns these img tags into real normal img tags. The truth is that the Javascript about loading individual sections is a bit more complicated but in its inner core it looks something like this:

// variable 'hash' is something like 'page2'
if ($(hash + '.section').size()) {
  $(hash + '.section').show();
  $('img.deferred', hash).each(function() {
    var el = $(this);

It makes the HTML slightly more complicated but the end result is great. It's not just useful for the first-time load but also applicable every time someone reloads the page.



"." and "" are are valid URLs in some browsers.

You might need to do something slightly more complicated or use a "no image" image.


Great! Thanks for the heads up


the solution sucks

Your email will never ever be published

Related posts

Postgres collation errors on CITEXT fields when upgrading to 9.1 21 May 2012
Difference between $.data('foo') and $.attr('data-foo') in jQuery 10 June 2012
Related by Keyword:
To defer or to async JavaScript tags. That's the question. 29 June 2018
More CSS load performance experiments (of a React app) 25 March 2017
Images 30 April 2004