Putting an image on the page is easy, until it's not

I was reading Jake's analysis of F1 web sites and it was amazing (but surprising to me) that same issues keep on repeating.

Coincidentally around the same time, Ben Galbraith mentioned too me that he was looking for the canonical guidance on how to put an image on the page. Admittedly, I scoffed "It's just an img element innit?", but I bit and had a look.

I don't think I am out of touch with web development, but I certainly missed a trick to feel the pain the ecosystem has with images. On one hand Google is telling you to meet your Core Web Vitals and you must fix your images, but on the other hand the tooling is an absolute massive pain.

Squoosh helps you compress and validate that an image will look good; our guides on web.dev give you some concrete advice, but where do you start?

The modern image has gone from a simple <img> element, to requiring the author to think about the size of the image (in bytes); the size of the image (in resolution) for the target density; The codec being used (remembering the days of JPEG unless you want transparency) because support isn't even across the web; should the image be lazy loaded and pre-fetched?

It's complex. Very complex. You have to be an expert to get an image correct, and it's not actually clear the value an optimized image has. Which is why I think people keep it simple and don't bother.

The complexity of adding images to web pages is why the recommendation to "just use a CDN" is so attractive for the people who can afford it, but it's yet another centralization point and added complexity that you shouldn't have to care about.

I'm not sure what the path is out of this other than consistently making the tooling available to developers to do that right thing, with ease... So, during some recent downtime I built a prototype tool that creates the HTML for a variety of image codecs and image densities that should work well in a large amount of basic image use-cases.


A screen shot of the tool

The tool is not too complex and not too clever, either. You drop an image on the page and it will:

Why this strategy?

There is no real intelligence to the tool, I chose a heuristic that was relatively clear and easy to explain. A lot of images that we have trouble optimizing are the hero images on a page, so assuming 100vw makes and AVIF as the alternate preferred source just made sense to me.

AVIF seems amazing (the source image for this blog went from 800KB to 52 KB), yet it's not uniformly supported across the web. Chrome's support is good, so I decided to create this as a preferred <source> and then falling back to the optimized input image (e.g, PNG or JPG).

Setting the height and width is required for lazy loading and to ensure that we can lazyload and to prevent layout shifts.

Finally, the algorithm will halve the size of the image until it reaches a size of at least 200 pixels. This seemed like a reasonable trade-off in terms of enough sizes that the browser can pick from while also making sure we reduce the chance of artifacts created via sub-pixel resizing.

How was it made?

There's nothing amazingly special, at one point I was going to release it without the client-side image compression, but I wanted to see if it was possible to do everything with web tech.

I'll do a bigger blog post at some point, but the TL;DR is that I managed to work out how to integrate squoosh's CLI into an API of sorts.

I'm actually very keen to see the Squoosh team work on an web-side embedding API because I think it would be amazing if CMS's such as Blogger or Wordpress just quickly let a person not have to worry about optimizing the image at all.

Wrap up

Images are harder than they should be to get correct, and I'd love to hear your thoughts and feedback about what we can do to make it easy for developers to be on the happy path for the people that use their service.

I lead the Chrome Developer Relations team at Google.

We want people to have the best experience possible on the web without having to install a native app or produce content in a walled garden.

Our team tries to make it easier for developers to build on the web by supporting every Chrome release, creating great content to support developers on web.dev, contributing to MDN, helping to improve browser compatibility, and some of the best developer tools like Lighthouse, Workbox, Squoosh to name just a few.

I love to learn about what you are building, and how I can help with Chrome or Web development in general, so if you want to chat with me directly, please feel free to book a consultation.

I'm trialing a newsletter, you can subscribe below (thank you!)