AVIF and the format question
Two things happened to image formats this fall. The less exciting one is much more useful.
Two things happened in the last few months.
Chrome shipped support for AVIF, a properly new image format built out of a video codec, and one that produces smaller files than anything else we’ve had. That’s the exciting one and it got most of the attention.
And Safari 14 shipped WebP, which means WebP is now supported in every browser anybody is using. That’s the boring one and it’s worth considerably more to me this year.
WebP quietly became universal
WebP has been around since 2010. It’s been in Chrome basically forever, and the entire reason it never became the default is that Safari didn’t have it, so every site needed a JPEG fallback anyway, so you were maintaining two sets of files for a saving on some of your traffic.
That ended in September with Big Sur, and I don’t think enough people have noticed.
Practically: for photographs, WebP is usually 25 to 35% smaller than a JPEG at a quality most people can’t tell apart. It supports transparency, which means it replaces the enormous PNGs that exist purely because something needed an alpha channel. And it does animation, which means the 4 MB GIF can finally die.
You still ship a fallback, because you always ship a fallback, and older browsers and the odd email client and whatever a client pastes into a newsletter all still want a JPEG. But the fallback is now actually a fallback rather than the thing most of your visitors get.
If you only do one thing off the back of this post, it’s that: turn WebP on for photographs and stop thinking about it.
AVIF is better and awkward
AVIF is a bigger jump. On the images I’ve tested it’s frequently half the size of an equivalent JPEG, and it’s dramatically better at the low end, where JPEG turns into a mess of blocks and AVIF stays coherent. On large photographic backgrounds and anything with gradients in it, the difference is not subtle.
Three things make it awkward right now.
Encoding is slow. Not “a bit slower,” properly slow. On a large photograph I’ve watched it take the better part of a minute where a JPEG takes a fraction of a second, and on a site with 400 images that turns a two-minute build into something you can’t run in CI without thinking about it.
It’s one browser. Chrome and the Chromium browsers. Firefox is close, Safari isn’t. So it’s an addition to your set of files rather than a replacement for anything, and now you’re generating three formats.
It isn’t better at everything. It’s built from a video codec, and video codecs are tuned for the things video contains, meaning photographic content. On sharp edges and small text, aggressive AVIF settings smear in a way that’s quite unlike JPEG’s failure mode and arguably worse, because JPEG’s mess looks like an artifact and AVIF’s looks like your text is slightly out of focus.
AVIF fails differently rather than less. JPEG's mess looks like a compression artifact. AVIF's looks like your image is very slightly out of focus, which is harder to notice and harder to forgive.
There isn’t a flowchart
Everybody wants a decision tree, and I’ve tried to draw one twice, and the reason it doesn’t work is that the right answer depends on what’s in the picture rather than on what kind of file it is.
The useful questions, roughly in order:
Was it drawn, or was it photographed? If somebody drew it, it’s SVG, and this is the least ambiguous rule in the whole area. Logos, icons, diagrams, charts. Resolution-independent, usually tiny, styleable with CSS, and it gzips well because it’s text. Every logo I’ve ever received as a 300 KB PNG should have been 4 KB of SVG.
Does it contain text or hard edges? A screenshot of an interface, a photo of a document, a diagram exported as a bitmap. PNG is often the right answer here and can beat everything else, because lossless compression of flat colors is what it’s for, and every lossy format will make the type fuzzy.
Is it a photograph? Then it’s a compression trade, and that’s where WebP and AVIF live, and where the percentages above apply.
Does it move? Then it’s a video file, not an animated anything. An MP4 of a looping animation is routinely a tenth the size of the equivalent GIF and this has been true for a decade.
The markup, once
If you do generate multiple formats, the browser picks, and the order matters because the first supported type wins:
<picture>
<source type="image/avif" srcset="hero-800.avif 800w, hero-1600.avif 1600w" sizes="…">
<source type="image/webp" srcset="hero-800.webp 800w, hero-1600.webp 1600w" sizes="…">
<img src="hero-800.jpg" srcset="hero-800.jpg 800w, hero-1600.jpg 1600w" sizes="…"
width="1600" height="900" alt="…">
</picture>
Note that the <img> is still doing all the real work: it carries the alt text, the dimensions, the loading behavior and the fallback. The <source> elements are advice. And the width and height are there for the layout stability reasons I went on about in May, not for sizing.
This markup should be generated, never typed. It’s a shortcode, an include, a template partial. If a human is writing this by hand more than once you’ve built a maintenance problem rather than an optimization.
What matters more than any of this
Two things, and they’re both unglamorous, and they’ll beat every format decision on this page combined.
The dimensions. A 3000-pixel-wide image displayed in a 600-pixel slot is wasting roughly 96% of its pixels, and converting it to AVIF makes it a smaller waste. Get the dimensions right first and the format question becomes a rounding error.
The quality setting. Most images ship at whatever the export dialog defaulted to, usually far higher than anyone needs. Dropping a JPEG from quality 90 to 75 typically halves the file and is invisible in a blind comparison, and that’s the same order of saving as switching format entirely, for no build complexity at all.
I’d add a third: has anybody actually opened the file and looked at it since it left the designer’s machine. On most sites the answer is no, and the largest saving available is not a codec, it’s a person with a pair of eyes.
Where I’ve landed for now
SVG for anything drawn. PNG for text and flat graphics. WebP as the default for photographs, with a JPEG fallback, now that it’s everywhere. AVIF added on top for the two or three biggest images on the site, where the saving is worth the build time, and not for the other 400.
That’ll be wrong within 18 months, which is fine. Ask me again when Safari ships it and the encoders get faster, and I’ll write the same post with the nouns changed, which is a thing I appear to do 🙃