Optimizing images with the HTML <picture> tag

by jfhron 10/30/2022, 6:14 PMwith 48 comments

by gildason 10/30/2022, 6:53 PM

> I don’t think there’s a perfect answer. You simply cannot predict with 100% certainty what the browser would choose. But you can get a good approximation by parsing the User-Agent header

Isn't it the purpose of the "Accept" HTTP header? For example the last version of Firefox sends "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,/;q=0.8" when fetching a page.

by makeworldon 10/30/2022, 6:53 PM

> I’d still recommend including JPEG XL versions of your images, because chances are that browser support will come eventually.

Likely not. Chrome is actually deprecating JPEG XL, the news broke yesterday.

https://www.phoronix.com/news/Chrome-Deprecating-JPEG-XL

by jjcmon 10/30/2022, 7:47 PM

One caution here, as I'm just recently was working on automated image encoding for user submitted images - be careful of AVIF/JXL's encoding time.

I ran some benchmarks with a raw 48mp iPhone 14 dng file (converted to png to start with since jxl had issues going from dng directly) with imagemagick to illustrate.

jpg conversion: 1.74s

webp conversion: 3.77s

avif conversion: 67.96s

jxl conversion: 42.74s

Of course there's ways to optimize these, but still it's worth considering that these newer formats require an order of magnitude (if not more) increase in time to encode. If you're doing this for your own static site, it's worth doing. If you're dealing with user submitted images, make sure you understand the tradeoffs.

by lgreivon 10/30/2022, 7:30 PM

I am using the picture tag on my photography blog [1] to serve optimized images for a range of breakpoints. I also used to serve WEBP versions of the photos but noticed that (in my audience) the browser support was sufficiently low to drop the generation step for them and just serve various size/quality combinations of JPG. If time allows, I’ll also add a super low-res placeholder image in the background to prevent the slightly jarring layout jumps on slow desktop connections.

In combination with static hosting from S3 with CloudFront for caching, handwritten CSS + JS (except from Turbo), this yields a close-to-SPA snappiness and feel even on meager connections (as tested from rural Germany, fellow Germans may understand the implications).

The picture tag and the aspect-ratio CSS rule are real MVPs for dealing with photographs.

[1] https://44hz.de

by daxterspeedon 10/30/2022, 7:57 PM

A significant downside to the <picture> element, and alternative image formats in general, is that when most users wanna download the image they expect an image format they already know how to work with. To most users an .avif or .webp are an annoyance because they reasonable expect most of their tools to be unable to open these.

It's disappointing that browser vendors haven't picked up on this and offered a "Save as PNG/JPEG/GIF" option when downloading images, but for now if it seems reasonable that if any user would want to download an image you're displaying then you should probably stick to the legacy formats.

by jeffmcon 10/30/2022, 7:43 PM

For me the biggest win in pages with lots of images is the img loading=lazy flag- https://developer.mozilla.org/en-US/docs/Web/Performance/Laz...

This only loads the image when it scrolls into view

by sdfhbdfon 10/30/2022, 7:07 PM

> Safari doesn’t support the image/avif MIME type, so it will skip that one.

With iOS 16, current one, and newest Safari with macOS Ventura that support was added, see https://caniuse.com/avif

by evgpbfhnron 10/30/2022, 11:51 PM

Fun fact: the "Your browser support avif" image in that post at https://jfhr.me/your-browser-supports.avif is currently... a png file.

    $ curl -s https://jfhr.me/your-browser-supports.avif | file -
    /dev/stdin: PNG image data, 400 x 100, 8-bit grayscale, non-interlaced
(same for the jxl one, but firefox apparently doesn't try to load it because of the type. The webp and jpeg ones are what they say they are.)

by VoxPellion 10/31/2022, 12:05 AM

I would not use HTTP2 Server Push for anything, see: https://developer.chrome.com/blog/removing-push/

by Null-Seton 10/30/2022, 6:49 PM

The title lost the essential "picture" tag part of it, probably to html sanitization

by d_budon 10/30/2022, 6:57 PM

MDN says that img tag purpose is not just to serve as a fallback, but also to specify size “and other attributes”. Does it also include alt attribute? This is important. Can someone confirm that?

by Paninoon 10/30/2022, 9:07 PM

You can also use the picture tag to serve different images based on the browser's dimensions, to serve the best content and fast. So people with a TV get a wide image while a phone gets a small version, for example. The browser itself makes the choice and GETs the image from a list in the picture tag.

This could also conceivably be used for user tracking purposes as a way to determine without javascript the user's browser window setting. (I assume CSS can do this too.)

by Flocularon 10/30/2022, 7:47 PM

This made me look up jpeg2000 support. And then that made me sad :D

by spepson 10/30/2022, 6:49 PM

FTFY: HTML <picture> tag