tl;dr: Use responsive images and asynchronous loading to lower initial page weight by ~80% and improve the Speed Index. For further improvements, use mozjpeg smartly to reduce JPEG file size for initially visible images and consider alternate formats such as BPG for initially invisible images.

High performance images are hard: compression techniques are complex and media formats are mind-boggling. But we need images: they elicit emotional responses – the key to successful conversions.

Images form the largest part of all website data - via HTTP ArchiveImages file types distribution - via HTTP ArchiveThat’s why images make up 23 of all website data and JPEGs, being the predominant image format, account for half of all image data. They also account for ~20 HTTP requests per page.

This impacts both the Speed Index, indicator for a good user experience, as well as the total page load time. Large images at the top, called “Hero Images”, may be detrimental to the Speed Index, while the total amount of image HTTP requests and image data size causes a slow page load time.

To optimize website performance for both Speed Index and page load time, let’s take a progressive enhancement approach: starting with a simple demo page as baseline, we’ll add several enhancements to the image loading and rendering process.

The baseline demo page shows 20 JPEGs, weighing in at ~1.6 MB raw data. It has a basic responsive layout using fluid rescaling for images. To find our measurement baseline, we’ll run performance tests via WebPagetest for both desktop and mobile, focusing on Speed Index and page load time. As a secondary objective, we’ll keep an eye on page weight and the resulting costs on a mobile data plan because it’s common courtesy not to waste our users’ bandwidth.

Baseline

Speed Index Page Load Time Page Weight Cost
Desktop 778 2,995s 1.643kb $$$$-
Mobile 1252 5,064s 1.643kb $$$$-

The first enhancement is implementing native responsive images, courtesy of Yoav Weiss. We’ll be using the element and the pictureFill Polyfill. Responsive image sizes are 480, 768 and 940px, compressed using ImageOptim.

Responsive Images

Speed Index Page Load Time Page Weight Cost
Desktop 702 3,329s 1.643kb $$$$-
Mobile 1169 3,186s 450kb $$—

The biggest winner of implementing responsive images is page load time on mobile: 2s less resulting from a whopping page weight reduction by 1.2MB. The Speed Index did not change significantly because the JPEGs in the demo were progressive from the start.

For the second enhancement, we can improve on this: by adding lazysizes.js, we introduce lazy-loading of images below the fold. Everything above the fold stays untouched to keep the Speed Index low. A good lazy-loading threshold for your own website would be the vertical browser window height of >90% of your visitors.

Responsive Images + Lazy Loading

Speed Index Page Load Time Page Weight Cost
Desktop 690 1,199s 322kb $—-
Mobile 1172 1,601s 95kb $—-

This time, we managed to cut both desktop and mobile page load times in half as a direct result of 7 instead of >20 HTTP requests, thanks to lazy loading. Also we have successfully lowered the initial page weight by ~80%.

Implementing responsive images and lazy loading reduces page weight by 80%

Responsive images and lazy loading are great ways to reduce the initial image weight of your website. To increase those gains even further and to impact the Speed Index, we will get creative:

In our third enhancement, we’ll optimize all traditionally loaded above-the-fold images. The large image at the top, the “Hero Image”, is best compressed carefully to avoid compression artifacts, so we’ll use Adept. The three smaller images will benefit from rigorous compression, so we’ll use cjpeg-dssim to automagically discover the optimal lossy compression ratio for mozjpeg.

RespImg + lazy + adaptive JPEG compression

Speed Index Page Load Time Page Weight Cost
Desktop 591 1,003s 182kb $—-
Mobile 1150 1,364s 60kb $—-

These enhanced JPEG compression techniques yield ~25% file size savings for the hero image and ~50% file size savings for the three smaller images above the fold. The smaller image file size has a positive impact on the Speed Index because images will start rendering sooner. Website size savings are ~45% in our demo, which also improves the total page load time.

In our fourth & last enhancement, we’ll reinvest some of those file size savings to gain a performance improvement later: switching images to the BPG image format for below-the-fold content yields savings of another ~56% in total image file size for our demo page. This is thanks to BPG’s use of HEVC compression.

The use of BPG comes at a cost, however: as it is not a natively supported image format, we will have to include a Javascript based BPG decoder, which enables browsers to show BPG images. This decoder weighs in at ~60kb gzipped or 190kb uncompressed – which we are able to offset since the BPG file size savings for our demo page are >191kb.

RespImg + lazy + adaptive JPEG + BPG

Speed Index Page Load Time Page Weight Cost
Desktop 770 1,021s 275kb $—-
Mobile 1100 1,356s 61kb $—-

The initial test results for the BPG image format don’t show any significant improvements for our demo page compared to prior enhancements. This is, however, because the tests only load the JPEGs that are still being used above the fold. If we scroll down and start loading BPG images instead of JPEGs, the file size savings accumulate quickly:

BPG image format file size savings

JPEGs BPG
Desktop 2.053kb 1.319kb
Mobile 560kb 490kb

Scrolling can’t be tested properly with WebPagetest, so open your browser’s developer tools network tab to see the behaviour. Also note that while BPG offers great file size savings, its Javascript based decoder will have a significant CPU impact.

That’s all, folks!

With a few enhancements, we converted an image-heavy, costly page with both mediocre Speed Index and total page load time to a speedy, smart page that respects our users’ bandwidth and has both a good Speed Index and page load time on desktop and mobile.

Credits: Thanks to Alexander Farkas for helping to get lazysizes to work with BPG, thanks to Corinna Baldauf, Colin Bendell, Gareth Hughes & Desmond Tam for proof-reading. Demo page images under Public Domain, text fragments taken from Herman Melville’s Moby Dick
Webpagetest Testing Methodology: WPT Dulles, Chrome, 7000 Kbps DL / 2000 Kbps UP, 28ms latency for desktop tests, 150ms latency + Chrome mobile browser emulation for mobile tests, showing the median result from 9 test runs per iteration

ABOUT THE AUTHOR

Tobias Baldauf (@tbaldauf) is a web performance evangelist and consultant at Akamai. He creates DevOps tools, image optimization algorithms & speaks at conferences. He's a proud dad, mindful veggy & music lover.

6 Responses to “Immaculate Imagery with Lazy Pictures & BPG”

  1. Brian LePore

    What browsers actually support BPG? I thought browser support for it was bad at this time and that you needed a JS library to add support.

  2. Brian LePore

    Sorry, missed that you mentioned that in the article.

  3. Steffen

    So lazy loading helps a lot when 2/3 of all website data are images, especially in mobile networks. But then I’m wondering why a native lazy loading solution does not seem to be a top priority for browser vendors. The lazysizes script by aFarkas is great but requires changing the markup to use data-* attributes.

  4. Francis Kim

    First time coming across BPG – thanks :3

  5. Tweet Parade (no.51-2015) - Best Articles of Last Week | gonzoblog

    […] Performance Calendar » Immaculate Imagery with Lazy Pictures & BPG – Use responsive images and asynchronous loading to lower initial page weight by ~80% and improve the Speed Index. […]

  6. Web Development Reading List #118: Opera Mini, BPG Format, Accessible Tabs and Flexbox - American Fido

    […] Baldauf shares how we can optimize our imagery on websites to be as small as possible12, using lazy loading, responsive images, and, if it’s applicable, the BPG image format via […]