Images 101
There are plenty of ways to pin an image resource on a web page. In this article I will try to summarize some of the popular methods and when to use them for maximum performance.
<img src>
The classic and semantically correct way of showing image resources on a web page. However it does not do that well for the modern high pixel density devices, since you can have one and only one resource in the src
attribute, right?! …WRONG! Meet srcset - a spec draft for a new attribute extension to the <img>
that will allow you to specify multiple image resources to be displayed according to the client’s screen type.
This is work in progress and we wont see it any time soon, but it looks so much better than everything else you are about to read.
data-uri
This is probably the least useful way of showing an image, because it bloats your html code with big, fat, unmaintainable chunks of base64 strings. It wont utilize the browser’s cache, since the resources are inlined and the only benefit that one could see is the reduced amount of requests. Recently it was empirically proven to be slow.
web fonts
Web fonts are flexible way to define your own representation of the unicode characters, which means that you can map different shapes to different symbols and these shapes will behave exactly like text characters. You will be able to change their size, color, set a text shadow and they will look sharp on any screen, because the fonts are vector graphics. This is quite handy and massively used for icons. The only real downside is that the initial downloading of the font file happens very late in the page load and no icon will be visible before the entire font file is loaded. Other than that you have to make sure to be ARIA compliant and text reader friendly.
sprites
Using sprites is an effective way to reduce the number of http request and your initial page load time. If you have many small images, instead of making a separate request for each one of them, you could fetch a single image file containing all of your image components and show different segments of it. The main disadvantage of this approach is that you have to use the sprites as a background of a html elements with fixed dimensions corresponding to the segment you want to show. You could outsource all the hard work of generating sprite images and corresponding css code to compass and make your life simpler. Use this approach whenever web fonts are not an option.
conditional loading with media queries
The media queries in css3 enabled conditional styling depending on the browser’s screen size and pixel density. Which means that you could define several version of a background image with different sizes and only the one matching your media query will be loaded and used. The trick is very similar to the sprites - the image is again loaded as a background for a specific html element(s).
In fact you can combine this and the sprites trick and have a crisp, high-pixel-density-ready sprite images.
svg+img hack
Recently I read about a cool hack to display svg graphics whenever possible and fallback to png in case svg is unsupported.
However that code will make 2 http request - one for the svg and one for the png, but then I stumbled upon an even crazier hack in twitter.
So that SVG/image shortcut I RT'd makes extra requests (via @chriscoyier). I think I prefer <img src="foo.svg" onerror="this.src=foo.png">
— Scott Jehl (@scottjehl) August 18, 2013
This could set you free from all the crazy media queries at least for part of your images in case you have corresponding svg versions of them. Also the svg files are smaller and will be loaded faster than the png files bringing you performance optimization.
All the tricks mentioned in this article are more or less hacks (or at least inconvenient) or non-existing yet, but this is how the Web works for now. Use them wisely and they will serve you great.