Addendum

Support for JPEG XL has continued in subsequent iOS and macOS releases, and it is an excellent format to leverage if Apple users are a significant portion of your audience, which is usually the case. Outside of that, support remains very limited.

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.

A billion+ devices now support this best-in-class, feature-rich image format, which is a stark change from the very limited support it previously saw.

This is it. It’s finally time to move on from the thoroughly obsolete JPEG format! Okay, in reality JPEG will hang around forever, but you do have a superior format option for some of your users, and hopefully in the years ahead some of the other browsers get with the century.

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 srcs on a need basis, or client-side feature sniffing scripts, and thankfully that sort of heavy-handed solution is entirely unnecessary. There are also server-side options such as subbing JXL for JPEG if the accepts header indicates, but that is not the scope of this, and often isn’t an option when you don’t control the proxy server or are static hosting.

And just to be comprehensive, another option is to use a script block in the page that executes post-document load but before rendering or network requests kick off. Such a block could react to JXL being supported by finding JPEGs in the document and subbing them out for JXL. That’s a topic for another entry.

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 images3, 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, benefitting from 30-50% smaller files. In new workflows you can go right to JPEG XL from your high quality originals for peak quality. This is where JPEG XL leaps far ahead of AVIF/HEIC.

  • Supports HDR

  • Supports lossless compression, critical for some uses

  • 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 hopefully those will arrive over time.

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 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>
flowers

That’s it! It really is that easy.

Users on the iOS 17 or later will get the JPEG XL image, as will those on macOS 12 onwards. Those on Chrome and Firefox will likely get an AVIF image. Edge, despite being Chromium underneath, will fallback to the WEBP image at the time of writing (there seems to be a licence 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

Hopefully Chrome and its various offspring (Edge, etc.) (re-)support JPEG XL4 in the 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. With enough awareness the case is definitely there to make the switch, especially for situations where image fidelity is critical.

Footnotes

  1. 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 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

  2. 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

  3. 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

  4. 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 hopefully leads to the eventual outcome that Chromium puts it back in