optimize-images examples

A large, uncompressed image

This image is 2.1MB uncompressed, and it is 4032 x 3024, and a jpg. This may take a second to load, and it should feel kinda crappy to your browser.

An image

If you want to see how it could feel crappy, open your browser’s DevTools and click on the “Network” tab. Click “disable cache” and then reload the page. On my machine, this image takes 87ms to load — the optimized image below takes 12ms. While this may not seem much in practice, I’m running these benchamrks on my local machine so it’s the optimal speed for transfering data.

Now, click “no throttling” and then select “Fast 3G”, which is arguably the speed at which most of the world operates at1. For me, this takes 15.48s to download, of which 14.90s of that is actually downloading the image. This is only 5.29s for the optimized image and 3.82s of download time.

A large, compressed image

The image above has been automatically compressed to 1200x1600, in the optimized webp format, down to 233KB. That is a 10x decrease in size for a 4x reduction in pixels, approximately. It has also generated images in widths of 800 and 400, which will be requested by the browser if on a sufficiently small device.

An image

The generated HTML looks like this:

<img src="images/norman-tsui-AB8Vn19fgaE-unsplash-1600w.webp" class="img-fluid" style="aspect-ratio: 4032 / 3024" srcset="images/norman-tsui-AB8Vn19fgaE-unsplash-1600w.webp 1600w, images/norman-tsui-AB8Vn19fgaE-unsplash-800w.webp 800w, images/norman-tsui-AB8Vn19fgaE-unsplash-400w.webp 400w" decoding="async" alt="An image">

In addition to the generated files, it also adds a few extra pieces of metadata. We specify the aspect-ratio so the browser is capable of pre-calculating the amount of space the image needs before it loads it. We specify decoding="async" so the browser can asynchronously load the image, rather than blocking.

We also add some metadata in the <head> specifying the image preloads as per best practices.

<link rel="preload" as="image" href="images/norman-tsui-AB8Vn19fgaE-unsplash-400w.webp" imagesrcset="images/norman-tsui-AB8Vn19fgaE-unsplash-1600w.webp 1600w, images/norman-tsui-AB8Vn19fgaE-unsplash-800w.webp 800w, images/norman-tsui-AB8Vn19fgaE-unsplash-400w.webp 400w">

While this does theoretically increase HTML bloat, modern browsers are obviously very optimized at reading HMTL extremely fast. Indeed, since we move the image preloading to the <head>, browsers read HTML sequentially so it becomes aware of the image far before it would through walking the <body>.

Images don’t get upscaled.

Here’s an image that’s 1200x1200. We’ve defined our thresholds as 1600, 800, 400, so we don’t want to upscale it.

An image

The optimized image generates sizes of 1200, 800, 400. It generates the “highest” optimized width possible and everything that’s smaller.

An image

This also applies to even smaller images. Here’s an image of size 600x600 — it wouldn’t make sense to generate an 800x800 image for this. This filter handles this edge-case, and generates a 600x600 webp and a 400x400 webp.

An image

Finally, here’s a small image at 300x300 — the filter only generates an optimized webp, and doesn’t perform any downscaling.

An image

Appendix: why is optimizing images important?

Optimizing images is probably the thing you most need to do on any website. Images are binary content that can’t necessarily be optimized away, as it is vital to the content of your website.

Additionally, from the perspective of SEO, Google and other search engines heavily dock websites that aren’t well-optimized. By failing to not optimize, you’re destroying discoverably for your own content. And indeed, to people in the world that may have worse internet connections than you, they’re likely going to just avoid reading your content if it takes too long for it to load in their browser.

Footnotes

  1. It’s about 1/3 from my understanding↩︎