Effortlessly Support Next Gen Image Formats
Spoiler: This piece recommends that you use the picture
element, prioritizing better image
formats in your web applications while still supporting legacy clients. If you're already using it you can
probably click back.
The verbiage below is hopefully helpful for everyone else
Apple Throws In Behind JPEG XL
At WWDC 23, Apple announced that they will support JPEG XL1 in their upcoming software releases2. Not only in their new OS products, but in their Safari 17 release which can be used from macOS Monterey onwards.
In mere months from now, a billion+ devices will support this best-in-class, feature-rich image format, which is a stark change from the very limited support it currently endures.
This is it. It's finally time to move on from the thoroughly obsolete JPEG format! No, seriously, we've talked about this for years, but now it really is the turning point.
We've had broadly-supported superior formats for years in the form of WEBP and AVIF (both derived from video codecs). Supported by most major browsers, these were already a huge step up from JPEG, offering dramatically better visual performance at much higher compression levels. They did have downsides, however, notably the lack of progressive rendering, and a significantly higher computational complexity to decode versus JPEG. It was easy to pull a "no one gets fired for buying IBM" sort of fallback-to-defaults easy out and just stick with JPEG. JPEG XL has neither of those downsides. It is nothing but upside, beyond adapting your content work process slightly.
In this entry I'm focused specifically on the web side of things, and how you can serve JPEG XL to capable clients with fallbacks for clients that don't yet support it, and will use the same approach to serve WEBP and AVIF as well. I use it in my own projects to prioritize SVG as well (many images are optimal in vector formats, but that's another article), offering raster fallbacks for those who need it.
This is super trivial, yet I've seen users on software development boards proposing
solutions such as inserting a client-sniffing reverse proxy that replaces img src
s on a need
basis, or
client-side feature sniffing scripts, and
thankfully that sort of heavy-handed solution is entirely unnecessary.
Why JPEG XL?
There are loads of great resources comparing the formats, including comprehensive A:B type comparisons, so I'll simply list the major advantages of JPEG XL.
- Dramatically better visual quality at the same file size as JPEG. Better than WEBP, while competitive with AVIF/HEIC. JPEG XL even bests PNG at non-photorealistic content like charts and figures, making it an all-purpose solution for images.
- Supports transcoding existing JPEGs with zero re-encoding loss for your existing images4, while still offering great size savings. If you have thousands of existing JPEG images, you can transcode them to JPEG XL with no re-encoding loss, generally yielding 30-50% smaller files. In new workflows you can go right to JPEG XL from your high quality originals.
- Supports HDR
- Supports lossless compression, critical for some industries
- Supports transparency/alpha channels. Not just a mask, but a full channel facilitating varied transparency. It actually supports arbitrary channels for any nature of additional data, such as depth data, making it an incredibly flexible format.
- Supports animation
- Fantastic decoding speed, so it's fast and efficient. Gentle on processors and batteries.
Not every client is going to support every feature out of the gate — Safari 17 on iOS 17 doesn't support animations for JPEG XL yet, for instance — however with adoption these will certainly come.
JPEG XL is a viable replacement for JPEGs, PNGs, GIFs, among other formats. With the prior next-gen formats there were legitimate pros and cons. With JPEG XL it is literally all upside, presuming you have the fallbacks while laggard clients catch up.
Introducing the picture
Element
Supported in every major browser, the picture
element's is primarily leveraged for its media conditions, offering a responsive design facility that varied
which image
was used
depending upon the traits of the display device. A smaller display might load a smaller picture while a
high DPI
displays might use a high resolution image, and so on.
The picture
element supports backwards compatibility by hosting an internal img
element. If the client doesn't recognize the picture
and source
elements, it will
ignore those entirely and use the img
element
instead. Similarly the img will be used if none of the types or media conditions match the client.
In this entry I'm going to focus on the type
attribute offered by source
children
of the picture
. By specifying the
mime type for a series of images in a set of picture
> source
children, the
browser
will find the first image that matches its supported
formats, loading and using that option. You can of course combine these with media conditions for
type+responsive condition optimizations.
<picture>
<source type="image/jxl" srcset="./jpegxl/flowers.jxl">
<source type="image/avif" srcset="./jpegxl/flowers.avif">
<source type="image/webp" srcset="./jpegxl/flowers.webp">
<img src="./jpegxl/flowers.jpg" id="flowers_image" alt="flowers">
</picture>
That's it! It really is that easy.
Users on the beta of iOS 17 will get the JPEG XL image. Those on Chrome and Firefox will likely get an AVIF image. Edge, despite being Chromium underneath, will fallback to the WEBP image (there seems to be a license or patent concern leading Microsoft to isolate AV1/AVIF functionality). Browsers that support none of those will get a classic, terrible JPEG.
Browsers that don't understand the picture element will act as if they don't exist and simply display the
img
.
Browsers that understand it will evaluate each line to find the first that matches a supported type and, if
applicable, media criteria.
From a DOM perspective the img is still king, and the resolution of the picture/source artifacts will modify
the img element. You can test the currentSrc
property of the img
to determine
which image it selected, as was done on this page to fill out that info below the images.
And of course JPEG XL is a replacement for PNG scenarios as well. For instance a logo (in this case for my own employer) where I will attempt to use the optimal vector graphic, but for those who don't support it I fallback to the hyper-efficient JPEG XL, failing that using a PNG.
PNG is a fantastic format for uses like this, but still the JPEG XL is almost 1/5th the size: 9,778 bytes versus 44,530 bytes for the PNG. The SVG is close to the JPEG XL size, at 10,516 bytes, however it has the advantage of rendering perfectly at enormous resolutions.
<picture>
<source type="image/svg+xml" srcset="./jpegxl/yafla_logo.svg">
<source type="image/jxl" srcset="./jpegxl/yafla_logo.jxl">
<img id="logo" src="./jpegxl/yafla_logo.png" alt="logo">
</picture>
Note that the checkerboard pattern is added to the background container to demonstrate the transparency which all three of the possible formats (SVG, JPEG XL, and PNG) support.
Where It Goes From Here
There is a high chance that Chrome and its various offspring (Edge, etc.) (re-)support JPEG XL3 in the near future. In fairness, I should offer up the counterpoint that Safari, both mobile and desktop, has supported JPEG2000 for over a decade with little impact on the computing world, the format still wallowing in obscurity.
JPEG XL offers a much greater value proposition over classic JPEG than JPEG 2000 did, with the latter basically offering only a higher compression ratio. JPEG XL, in contrast, offers transparency, HDR, animations, additionally compressing JPEGs with zero quality loss, lossless compression, and a number of other real-world benefits that can improve many workflows and bring real benefits for end users.
Footnotes
-
Safari 17 also adds HEIF/HEIC support, which has always been a bit of a split brain situation on Apple platforms. Use iCloud Photos from Safari and it presents all of the photos as JPGs to your browser (given that it didn't support HEIC), but if you download while using a macOS client it downloads a less compatible HEIC variant that is a pain if you need to upload it to a website, with few supporting the format. If you access the same site from a Windows machine and choose the lower quality option it gives you a JPEG version. HEIC (which is another format derived from a video codec, as with wep and avif) is a big upgrade over the original JPEG from a visual fidelity perspective, but most of the time it's a big hassle to deal with. Hopefully with JPEG XL we see the magical combination of better visual fidelity and wide support↩︎
-
Relative to the time that I authored this, 2023-06-07. The betas of iOS/iPadOS 17 are available now and support JPEG XL. The Safari 17 beta for macOS 12+ will be available in the coming months↩︎
-
https://news.ycombinator.com/item?id=33933208 - prior discussion regarding "JPEG XL support has officially been removed from Chromium". I get why Google removed it, as it was a classic chicken/egg situation: With the feature poorly supported in browsers, where even on canary copies of Chrome it was hidden behind a flag, there was no benefit for content creators to support it. Every line of code represents security and maintenance concerns so eventually they pulled it. Adding 1B+ Apple device users fully supporting the format is going to completely change the algebra around adopting the format, and it is incredibly likely Chromium puts it back in↩︎
-
Check out libjxl library, allowing you to compress files to JPEG XL and to transcode existing JPEGs to more efficient JPEG XL with no quality loss. Many other tools, like ImageMagick, support JPEG XL as well. Photoshop at this point won't save as JPEG XL (yet), however it will open them via the "Camera Raw" import functionality↩︎