The BBC has a server-side image service which provides developers with multiple sized versions of any image they request. It works in a similar fashion to http://placehold.it/ but it also handles the image ratios returned (where as placehold.it doesn't).
The original BBC News process (and my re-working of the script) follows roughly these steps...
- Create new instance of ImageEnhancer
- Change any
div
s within the page (which have a class ofdelayed-image-load
) into a transparent GIF using a Base64 encoded string.- We set the
width
&height
HTML attributes of the image to the required size - We know what size the image needs to be because each
div
has customdata-attr
set server-side to the size of the image - We then set a class of
image-replace
onto each newly created transparent image
- We set the
- We use a 250ms
setTimeout
to unblock the UI thread and which calls a functionresizeImages
which enhances theimage-replace
images so their source is now set to a URL where the returned image matches the requested dimensions in the URL path (in my example below I userequestAnimationFrame
instead)- We also create an event listener for the resize event which fires a pubsub event of
imageEnhancer:resize
- We also create an event listener for the resize event which fires a pubsub event of
- We call
resizeImages
initially and then every time the pubsub event fires.- This function loops each
image-replace
image and changes thesrc
attribute to the new URL with the best possible match dimensions specified within the URL path (based on the dimensions required for the image). - If the resize event fires then we check the dimensions of the page and determine if we need a new URL to be used.
- This function loops each
The example code that follows is not production ready, you can't just drop it into your code base and expect it to work. It is a rough prototype I built in about 30 minutes to help demonstrate in a roundabout way how the BBC News responsive team were handling the enhancement of images. The code uses features only available to more modern browsers (e.g. I've tested it in Chrome 28 and nothing else so your mile may vary if you're using a different browser to look at the example).
I've also used the http://placehold.it/ service in place of the actual BBC News image provider. They don't work in quite the same way, but if you open the following HTML code in a modern browser (e.g. Chrome) and resize the browser window downwards you'll see the images change based on the current window dimensions. So rather than load a large image for smaller screens we swap out our images with images that are optimised for that screen size.
Notes about the rewritten example:
I should use livenodeList
otherwise we'll miss any images added to the DOM after ImageEnhancer is initialised.- I might be able to work-around the use of the base64 image
- Look at caching of image loads
@addyosmani that is correct yes, it is much more cross browser friendly and utilises less modern API's. but for the sake of simplicity in demonstrating the principles of the code I avoided worrying about cross browser support while carrying out this quick rewrite :-)