Back in May I shared how to load images asynchronously with JavaScript.
I had a lot of requests from people on how load images using jQuery. So here we go!
Contents
Asynchronous Image Loading
Instead of having images load like this:
We want them to appear when it’s ready, like this:
Overview
Whether you’re loading a high-resolution image in an image gallery or you have a game with lots of image assets and sprites, the code will do something like this.
- Create an
<img>
tag programmatically with jQuery. - Assign an on load event handler so when the large image loads it assigns the new image url to the new image.
- Assign a URL to the
src
attribute of the new image.
Setup
The HTML
The HTML is straight forward, a simple image.
I’m using a gif with 1 clear pixel that get’s stretched over the whole image tag. If you don’t use an image you’ll get a “missing/broken image” icon like this:
Alternatively you can use a low-resolution of the image you’ll eventually show and when the high-resolution, high-quality image downloads you can swap it out. This is a more progressively enhancing approach.
The CSS
In my example, I’ve included some CSS that will add a loading.gif
in the background of destination image tag.
To get this effect, I used the following CSS.
This centers the loading.gif
into the middle of the destination image.
The jQuery
Firstly, make sure you have jQuery included in your project. Next, use jQuery to select the image you want to eventually insert the large image into. In my example, it’s the first image on the page.
Then I need to create an image programmatically. In jQuery, you can just select the string of the tag you want to create.
Once you set the src
attribute on this image downloading will start. Before that, we want to ensure that we have a handler for the onload
or load
event. Once the image had been downloaded this handler will trigger.
We want to set the destination $image
source to the $downloadingImage
source. The reference to $this
inside the handler is the $downloadImage
. We should use this
since in the handler just in case we use this same handler for other images.
Last but not least, we want to set the $downloadingImage
‘s source attribute.
This will start the image download in the background immediately. Once the download is finished, the load
callback will be triggered. The destination’s image source will be that of the newly downloaded image. And that’s it!
Here’s the complete jQuery code:
Final Thoughts
Using jQuery to do this rather than “Vanilla” JavaScript is fine if that’s what you’re comfortable with. But if you’re only loading images asynchronously, there’s a similar amount of lines of pure JavaScript as there is to jQuery. But jQuery has an additional overhead – it needs to be downloaded, evaluated and ran – with pure JavaScript you don’t have that overhead.
If you feel like your want to get out of your comfort zone and learn pure JavaScript versions of the jQuery API you should take my Treehouse course Interactive Web Pages with JavaScript. Or if you’re still learning jQuery, try my jQuery Basics course!
Nice Tutorial for loading images without affecting browser performance
The technique works in Chrome 48 but I’m concerned that it will fail on some browsers. The jQuery documentation at [ http://api.jquery.com/load-event/ ] states that:
*) It doesn’t work consistently nor reliably cross-browser
*) Can cease to fire for images that already live in the browser’s cache
Both issues would be really problematic!
I suggest storing the image URL in a Data attribute so that you aren’t forced to set the image URL for every single image in JavaScript…that is not practical in a real world app IMO. Something like
Nice tutorial. But if your goal is to not have standard jpegs loading top down, then I would suggest you simply save them as progressive jpegs and you effectively achieve a similar result, with the image loading into focus, and no additional code. I guess that would defeat the purpose of the tutorial, but I think it’s worth mentioning progressive jpegs as an alternative.
how would this work if you have to validate if the URL is not broken or if there’s a server timeout