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

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

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

  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 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↩︎

  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. 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↩︎

  4. 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↩︎

-->