High Performance Images: Beautiful Shouldn’t Mean Slow

Images on the web are getting bigger by the minute.

Over the last 3 years, image weight on the average web page has nearly doubled, growing to a massive total of 1.3MB per page. This growth is substantially faster than the (also fast) growth in JavaScript and CSS, and is only trumped by the 7x growth in font weight — much of which is also images (icon fonts).

Image weight and requests on an average homepage, over 3 years, per the HTTP Archive

Images are also the single biggest resource type on a page, making up 63% of overall page weight. If we removed all images from the top 1,000 websites, these sites would load 30% faster on average over 3G (per my tests using Andy Davies’s WebPageTest driver).

Still, rich visual interactions and beautiful images also offer plenty of value, and are clearly not going anywhere. However, there’s a lot you can do to minimize their performance impact. In this post, as well as tomorrow’s webcast, I’d like to offer a framework for gaining control over your images.

Image Compression

Image files are big. An average JPEG weighs 34KB, compared to 16KB for JS and 9KB for CSS. In part, this is just the nature of the beast, as a sharp image holds plenty of data, and that requires bytes. Another part, however, is because we didn’t encode them as well as we should.

The first step in compressing an image is choosing the right format. For instance, converting a (non-animated) GIF file to PNG would make it 21% smaller on average. Converting a (non-transparent) PNG file to JPEG can offer even bigger savings, often cutting file size by 3–5x. New formats such as WebP & JPEG XR can take it even further and communicate the same visual with 25–50% fewer bytes.

File size savings by using WebP, without reducing quality. JPEG XR offers great savings too.

Once you’ve chosen the right format, be sure to control your image quality. Serving a print-quality image on your web page can easily double its weight, and the difference in quality will not be noticeable on a computer’s display. A JPEG Quality of 75 is often a good starting target, and tools such as WebPageTest and PageSpeed Insights can help find images with excessive quality.

Image Loading

Once you’ve made your images as small as they can be, it’s time to think about when and how they’re loaded in a browser. From <img> tags to CSS background-image to icon fonts, there are many ways to show an image to a user, and they each have their own performance characteristics.

The most important step in image loading is choosing the right image for this device. Between the fragmented device landscape and RWD’s flexible images, websites today often deliver the same image to all displays, even when the displayed dimensions are dramatically smaller than those of the image. Serving right-sized images can save 75% of image bytes, reduce decoding time by 3–20x, and drastically reduce memory consumption.

Oracle is just one of many responsive websites serving big images to small screens

To implement Responsive Images (images sized to the display), use the new srcset attribute and <picture> element, which allow you to easily pick the image that’s right for the current display. The new capabilities are increasingly supported by browsers, and you can use Picturefill to cover the older clients. The Responsive Images Community Group is a great resource for examples and stay on top of this topic.

In addition, many of the images we deliver aren’t immediately visible. These images may be hidden with styles (but still downloaded), or simply require scrolling to achieve. Roughly 80% of downloaded images aren’t visible without scrolling (on the top 1,000, per my tests). On Medium’s home page, for example, only 4 out of 139 images are immediately seen.

To help the important images show up quickly, you can load those critical images using the native <img> (or <picture>) elements, and use JavaScript to defer the loading of images that may be “Below The Fold”. The Guardian’s website is a good example of doing just that. Other alternatives are to only load the remaining images when they come into view (lazy loading, to save on bandwidth); or to load all images natively but using a low quality, and use JS to swap them with higher resolution images as needed.

Image Operations

Lastly, you have to think about how to implement all your awesome techniques in the real world. If optimizing images is not integrated into how you develop and operate your website, you’re all but guranteed you won’t be good at it for long.

My first tip for image operations is to encode well. While image decoding is a standard, image encoding is not, and different tools can provide drastically different results. It’s important to know that Quality is also not a standard, and tools simply translate this metric into various other encoding parameters. Different tools are the right ones for different cases, but if you need one to start, check out ImageOptim, as it consolidates many others.

My second tip is to actually not encode locally, but rather use a proxy to transcode your images in realtime. The number of images, resolutions and image views will only grow, and you don’t want to find yourself re-encoding a million images when Apple ships their next device. A proxy can trancode images based on policies, path or query parameters, and will give you the agility you need while saving you costs. You can go DIY or find an Image Management “as a service” provider, but leaving image encoding to your CMS will simply not scale.

Learn More/Shameless Plug

One could write a full book about Image Optimization… And we’re doing just that! Tim Kadlec, Yoav Weiss, Mike McCall, Colin Bendell and I are writing a new O’Reilly book called “High Performance Images”.

Register to tomorrow’s Webcast to learn more and get a free copy of the e-book when it comes out.