On the hunt for the best image quality per byte.

A practical comparison of image formats for the web. JPEG vs WebP vs AVIF.

The Alliance for Open Media has come up with the image format AVIF, that got a lot of praise from Netflix. It’s based on the AV1 video codec. It promises to fit high quality images in even smaller file sizes than WebP or JPEG.

Support for AVIF has recently landed in Chrome and Cloudflare is actively marketing them featuring it as well.

As I have recently experimented a little with image processing services, I came up with a test setup to compare the different formats.

In case the AVIF images in this article dont’ show up correctly, please use a browser supporting AVIF today (e.g. Chrome).

Test setup

In my test setup I am using the following libraries in the specified versions:

How to compare

Setting the “quality” or “compression” to a fixed value in libwebp, libjpeg or rav1e for AVIF encoding will create fairly differently sized images and results that are not really comparable.

I am aiming to produce image files in the different formats that have comparable file sizes, so we can visually inspect the perceived quality from the same amount of image data.

The test image

original-image

This is an image taken by me on a sunny day closeby Fallbodensee in Switzerland. It features sharp edges around the mountains as well as soft areas on the lake and the sky.

Uncompressed at 1400x933px it is 820kb in size. This is a bit too much data for my taste to feature this image on a website.

I’m aiming to reduce the image size to just 10% of the original image (80kb). After some experimentation this has also proven to be a size where artifacts become visible.

JPEG (81kb) at 37% quality, generated in 128ms.JPEG (81kb) at 37% quality, generated in 191ms.

WebP (82kb) at 52% quality, generated in 303ms.WebP (82kb) at 52% quality, generated in 303ms.

AVIF (81kb) at 44% quality, generated in 1417msAVIF (81kb) at 44% quality, generated in 1417ms

Processing speed

Apart from the visual differences in my tests with the aforementioned stack is that generating AVIF images takes a higher amount of time longer than generating JPEG or WebP images.

When I started out my tests a single AVIF image could take around 6 seconds to be generated. rav1e and libvips (as of 8.10.2) support passing a speed parameter, that will change how much CPU effort goes into generating the image. Think of it like the compression value of a gzip. More effort = better compression.

Since I want to compare the image formats with a target use-case being the web, I have opted to go with the fastest speed 8 as any introduced latency isn’t desirable for the web.

Even if the results can be cached, the first response should execute in a timely fashion. Via the speed setting I got my response times down from the initial 6 seconds to 1.5 seconds, which I’d consider reasonable for the web.

Processing speed is something that is actively worked on for the rav1e encoder and the 0.4.0-alpha already made a near 100% improvement in that area. Since it’s an alpha and not yet integrated in libvips I am not using it for this comparison just yet. Going from 1.5s to 750ms would arguably be great for any request-response scenario.

To check how much on an impact the “speed” setting has, I generated the same image at the slowest speed 0.

AVIF (80kb) at 51% quality, generated in 3 minutesAVIF (80kb) at 51% quality, generated in 3 minutes

Yes, you read that right - 3 minutes to process the image into AVIF at slowest speed for best compression on the same machine that processes the JPEG in 120ms.

Interestingly I was able to up the quality by 7%, compared to the fastest speed setting - certainly the setting has a direct effect on the compression.

With this performance the best compression and slowest speed setting of the AVIF encoder is not a setting I’d turn on in a request-response scenario.

Zooming in on the results

Sky

You can already visibly see the sky and lake colours visibly losing quality and showing artifacts on the JPEG compared to WebP or AVIF.

Water

Here’s a section of the water. From first to last: Original, JPEG, fast AVIF, slow AVIF, WebP.


Original JPEG Fast AVIF Slow AVIF WebP

What we see is some surface detail staying in the JPEG and causing badly looking artifacts, whilst WebP and AVIF have a little lower detail and very low artifacts on the water surface.

This is similar to the situation in the sky parts of the image, where JPEG adds some sharp edges.

Impressively there’s quite a bit of a difference in how washed out the fastly generated AVIF is compared to the slowly generated AVIF that maintains some more detail.

Mountains


Original JPEG Fast AVIF Slow AVIF WebP

In any of the compressed image formats, there is a lot of detail lost on the side of the mountain.

The grainy artifacts of the JPEG are visually quite okay in this edge case - but the overall image quality has lost out to its competitor formats already due to the visible artifacts in the more smooth areas, like the sky and the water.

AVIF and WebP look to be on par here. The AVIF format with the highest CPU effort again retaining a little more detail.

Conclusion

Visually AVIF definitely blows JPEGs out of the water at high compression rates and in certain scenarios is more visually pleasing than WebP.

At the scale of Netflix it’s an absolutely sane choice - it’s a great image and video format!

Is AVIF worth an investment from you as a developer/company? Ready for prime time?

If you want your server to deliver AVIF images currently you may still be looking at a lot of patches across the stack as the file type may not correctly be detected by your webserver or application etc.

To compress images into AVIF you are also still looking at setting up a number of libraries from source.

With only 1 browser supporting AVIF currently, it certainly is not ready for prime time.

WebP has seen a very slow going (10 years) gradual adoption and is only now considered a format that can be used widely - the needed libraries and file type support should by now be part of any linux distribution you want to use.

If your main business is delivering images or video and you may also be in a space where you control the client (think e.g. instagram/Netflix) AVIF is certainly an option to save bandwidth whilst maintaining image quality.

This is certainly what it’s meant for. Until the libraries are more widely adopted I’d hesitate to make the investment to support AVIF just yet as a “regular” company or software developer.

Implement fallbacks - the Accept header ⭐️⭐️

Only 25% of browsers support AVIF and about 85% support WebP globally.

They all have one thing in common: They will announce in the request header that they do so: Accept: image/avif,image/webp,image/apng,image/*,*/*;q=0.8.

On the backend side its up to you to read out this information and serve the most optimal image format.

Implement fallbacks - the <picture> tag ⭐️

In case you don’t control the backend, the <picture> html tag is available in 96% of browsers globally and it allows us to specify the best image format for any given client.

<picture>
  <source type="image/avif" srcset="image/foo.avif">
  <source type="image/webp" srcset="image/foo.webp">
  <source type="image/png" srcset="image/foo.png">
</picture>

The picture tag also allows providing different resolutions for different picture sizes (e.g. for different devices). This is a great way to save bandwidth and making sure we’ll always use the optimal image format for the client. ⭐️

Instead of compiling libraries and patching webservers, maybe choose a service

More and more CDNs (like aforementioned Cloudflare), image processing services and OSS projects like imgproxy may support AVIF without you going through the hoops of fixing webservers and compiling the necessary libraries.

In light of more and more companies going “serviceful” I’d argue that is the right path if you want AVIF support right now, as alternatively you are looking at a fairly large amount of work.

The rate of adoption of AVIF is unknown at this stage, but I’d certainly expect that over time it’ll become as simple and fast to convert to AVIF as it is today to convert to WebP. The amount of work to support AVIF will decline eventually and thus my recommendation may change over time.

Personal outlook

I am currently working on an open-source release of the image processing server I used for this article. This may help you to have an option to produce AVIF images without compiling libraries and patching webservers etc.

Stay tuned for more and please ask away in the comment section below!

Special shoutout to all the maintainers behind the libraries I was using for this!


Published on 2020-10-14.