AVIF sub-sizes are larger than WebP at the default quality of 82

Aperta
#2,745 15 commenti 0 reazioni 1 assegnatario Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

@b1ink0 ci sta già lavorando.

Dal 3/11/2026.

  • #2746 di @b1ink0 — aperta

Valutazione

Questa issue non è ancora stata valutata.

Descrizione

[Plugin] Modern Image Formats [Type] Bug

Bug Description

AVIF is the default output format when the server supports it, but at the default quality of 82 the AVIF sub-sizes are larger than WebP, and often larger than the JPEG they replace. With "Output fallback images" enabled, webp_uploads_should_discard_additional_image_file() then deletes most AVIF sub-sizes for not being smaller than the JPEG, and the site serves only JPEG. Choosing AVIF gives a worse result than choosing WebP.

Encoder Affected since Why
GD WordPress 6.5 imageavif() has always received quality 82.
Imagick WordPress 6.7 Before 6.7 the quality never reached the AVIF encoder, so libheif's default of 50 applied. r59247 (#61614) fixed that, and AVIF files grew 2.7 times with no settings change.
Browser (client side media processing) WordPress 7.1 The image_quality REST field resolves wp_editor_set_quality for the output type, so the browser also encodes at 82.

The format is not the problem. At the same visual quality, AVIF is smaller than both JPEG and WebP (see the results below). The problem is that quality 82 means something different for each format.

Steps to reproduce

  1. Use WordPress 6.7 or later on a server where Imagick or GD can encode AVIF, with Modern Image Formats active.
  2. Go to Settings > Media, set "Image Format" to WebP and upload a photo (for example this JPEG).
  3. Set "Image Format" to AVIF and upload the same photo again.
  4. See that the AVIF sub-sizes in the uploads folder are larger than the WebP ones.
  5. Enable "Output fallback images" and upload the same photo again.
  6. See that most sub-sizes have no AVIF file, only JPEG.
Result

Tested on a fresh site with the official wordpress:php8.3-apache Docker image (Imagick 7.1.1-43 and GD) and the plugin from wordpress.org. The editor was forced through wp_image_editors. Four JPEG photos were uploaded with wp media import: the one above, kodim05, kodim23 and leaves.jpg. Plugin 2.6.0 is used on both 6.6.2 and 6.7, so only core changes between them.

WordPress Plugin Editor AVIF larger than WebP Median AVIF size vs WebP AVIF discarded with fallback on
6.6.2 2.6.0 Imagick 0 of 11 57% 0 of 11
6.6.2 2.6.0 GD 11 of 11 139% 9 of 11
6.7 2.6.0 Imagick 11 of 11 138% 8 of 11
6.7 2.6.0 GD 11 of 11 139% 9 of 11
7.1.4 2.7.1 Imagick 11 of 11 138% 8 of 11
7.1.4 2.7.1 GD 11 of 11 139% 9 of 11

For example, the medium size of the first photo on 7.1.4 with Imagick is 15,369 bytes as JPEG, 12,208 as WebP and 17,153 as AVIF.

Cause

Core's WP_Image_Editor::get_default_quality() returns 86 for WebP and 82 for everything else, including AVIF. The plugin's webp_uploads_modify_webp_quality() changes only WebP, to 82.

No image format defines what a 0 to 100 quality means. Each encoder library turns the number into its own compression setting, so quality 82 gives AVIF much more detail (and bytes) than it gives JPEG or WebP:

Library What quality 82 becomes Source
libjpeg-turbo (JPEG) Quantization tables scaled to 36% jpeg_quality_scaling()
libwebp (WebP) VP8 quantizer about 17 of 127 QualityToCompression(), VP8SetSegmentParams()
PHP's libgd (AVIF with GD) AV1 quantizer 11 of 63 quality2Quantizer(), gdImageAvifCtx()
libheif (AVIF with Imagick and the browser) AV1 quantizer 11 of 63 encoder_aom.cc

AVIF tools default well below 82: avifenc 60, PHP imageavif() 52, libheif 50, sharp 50 and Squoosh 50.

Before 6.7, Imagick only called setImageCompressionQuality(), but ImageMagick's AVIF coder reads the value set by setCompressionQuality() and skips setting the quality when it is undefined. r59247 was a correct fix that exposed 82 as too high for AVIF.

Which AVIF quality to use

Short answer
Where Goal Proposed AVIF quality Result
Core Look as good as JPEG 82, the WordPress default for JPEG 74 Looks at least as good as JPEG 82 on 83% to 97% of generated images, at about three quarters of the JPEG size.
Modern Image Formats Look as good as WebP 82, the plugin's WebP quality 70 Looks at least as good as WebP 82 on 79% to 94% of generated images, and is still 6% to 7% smaller than WebP 82.

The ranges cover the three editors (GD, Imagick and the browser). The details are below.

How it was tested
  1. Images. 384 openly licensed images of three kinds:

    Kind Images Source
    Photos 24 Kodak Lossless True Color Image Suite
    Photos 41 CLIC 2020 professional validation set (CLIC)
    Photos and some graphics 250 CID22 by Cloudinary
    Photos 4 The plugin's test images: leaves.jpg, paint.jpeg, car.jpeg, dice.png
    Diagrams 40 Featured diagrams on Wikimedia Commons, rendered to PNG
    Screenshots 20 Pages on en.wikipedia.org and developer.wordpress.org, half at normal and half at 2x (retina) resolution
    Screenshots 5 screenshot.png of the default themes Twenty Twenty-One to Twenty Twenty-Five

    The full list of files, with credits, is in the benchmark repository.

  2. Encoding. Each image went through the same steps WordPress uses, with the editor that does them on a real site:

    • GD and Imagick, through WP_Image_Editor_GD and WP_Image_Editor_Imagick from WordPress 7.1.4.
    • The browser, through wasm-vips 0.0.19 with the settings @wordpress/vips uses.

    Every size WordPress generates was saved as JPEG 82, WebP 70 to 94 and AVIF 50 to 90. That covers thumbnail, medium, medium_large, large, 1536x1536, 2048x2048 and the full size (scaled to 2560 when larger). This gives 1,463 generated images per editor and 153,615 encoded files in total.

  3. Server software. The official wordpress:php8.3-apache image: Debian 13, PHP 8.3, ImageMagick 7.1.1-43 with libheif 1.23.6, libavif 1.2.1 and libaom 3.12.1.

  4. Scoring. Each encoded file was compared with the uncompressed version of the same image using three image quality metrics:

    VMAF was also measured. It is left out of the decision because it is designed for video. Against JPEG 82 it asks for a higher AVIF quality (74 to 80) than the three image metrics do. Against WebP 82 it agrees with them.

How to read the tables

An AVIF file looks at least as good as the JPEG (or WebP) when all three metrics score it equal or better. For example, "83%" for GD means that 83 of every 100 generated images from GD look at least as good as the JPEG 82 version. File size is the median AVIF size compared with the JPEG (or WebP) file of the same image. 100% is the same size, and 72% means 28% smaller.

AVIF compared with JPEG 82 (the goal for core)

How often AVIF looks at least as good as JPEG 82 (higher is better):

Format and quality GD Imagick Browser
AVIF 66 50% 48% 34%
AVIF 70 65% 66% 82%
AVIF 72 72% 74% 94%
AVIF 74 (proposed for core) 83% 85% 97%
AVIF 76 88% 91% 99%
AVIF 78 92% 95% 99%
AVIF 82 (current default) 97% 99% 100%
WebP 86 (core's WebP default) 73% 72% 75%
WebP 82 (plugin's WebP quality) 39% 34% 40%

File size compared with JPEG 82 (lower is better):

Format and quality GD Imagick Browser
AVIF 66 61% 63% 60%
AVIF 70 65% 67% 70%
AVIF 72 68% 69% 74%
AVIF 74 (proposed for core) 72% 74% 76%
AVIF 76 75% 77% 81%
AVIF 78 79% 81% 84%
AVIF 82 (current default) 91% 93% 93%
WebP 86 (core's WebP default) 83% 84% 84%
WebP 82 (plugin's WebP quality) 70% 72% 72%

Compared with core's own WebP default, AVIF 74 looks as good as JPEG 82 more often (83% to 97% against 72% to 75%) and is smaller (72% to 76% of the JPEG size against 83% to 84%). AVIF 82 adds only a few more matches but its files are 22% to 26% larger than at AVIF 74.

Lowest AVIF quality that looks as good as JPEG 82 (lower means AVIF needs less quality to keep up):

Share of generated images covered GD Imagick Browser
Half 66 68 68
Three in four 74 74 70
Nine in ten 78 76 72

The typical image (half) needs only 66 to 68. A default has to work for most images, though, and 74 covers three in four or more on every editor.

By kind of image. Lowest AVIF quality that looks as good as JPEG 82 for half of the generated images:

Kind GD Imagick Browser
Photos 68 70 68
Diagrams 62 60 60
Screenshots 52 56 56

JPEG handles flat colours and sharp text poorly, so AVIF keeps up with it at a much lower quality on diagrams and screenshots. That is why the median over all images (66 to 68) is lower than for photos. Photos are the hardest case. Large photos (CLIC, 2048 pixels wide) need 72 with GD and 74 with Imagick.

AVIF compared with WebP 82 (the goal for the plugin)

How often AVIF looks at least as good as WebP 82 (higher is better):

Format and quality GD Imagick Browser
AVIF 66 58% 74% 38%
AVIF 68 70% 87% 71%
AVIF 70 (proposed for the plugin) 79% 94% 79%
AVIF 72 82% 95% 88%
AVIF 74 86% 97% 92%
AVIF 82 (current default) 91% 98% 97%

File size compared with WebP 82 (lower is better):

Format and quality GD Imagick Browser
AVIF 66 88% 87% 81%
AVIF 68 91% 90% 91%
AVIF 70 (proposed for the plugin) 94% 93% 93%
AVIF 72 97% 96% 98%
AVIF 74 104% 103% 101%
AVIF 82 (current default) 129% 129% 122%

At 74 and above, AVIF is larger than WebP 82. AVIF 70 is the highest quality that still saves bytes over WebP 82 on every editor. Unlike the JPEG comparison, the result does not depend much on the kind of image (the median is 64 to 72 for photos, diagrams and screenshots).

Newer AVIF libraries

The results above use the AVIF libraries in current Debian and Ubuntu packages. With libaom 3.13 or later, libavif 1.4.0 (used by GD) and libheif 1.22.0 (used by Imagick) switch to a new libaom tuning (tune=iq) with a different quality scale. The browser path already uses it (wasm-vips 0.0.19 ships libheif 1.23.5 and libaom 3.15.1).

To check whether this changes the answer, 73 of the images (all Kodak and plugin images, 30 CID22 images, 6 diagrams, 4 page screenshots and the 5 theme screenshots) were run again on php:8.3-cli-alpine3.24. That image ships libavif 1.4.1, ImageMagick 7.1.2-35 with libheif 1.23.4, and libaom 3.14.1. The same 73 images from the main run are used for the comparison.

AVIF 74 compared with JPEG 82, current and newer libraries:

Editor Libraries Looks at least as good as JPEG 82 (higher is better) File size compared with JPEG 82 (lower is better)
GD Current (libavif 1.2.1) 83% 72%
GD Newer (libavif 1.4.1) 98% 82%
Imagick Current (libheif 1.23.6, libaom 3.12.1) 86% 74%
Imagick Newer (libheif 1.23.4, libaom 3.14.1) 99% 74%
  • GD. PHP fixes the compression level for the quality number, and the new tuning spends more bytes on detail at that level. At the same quality number, files are about 7% larger and look better. AVIF 74 is still clearly smaller than JPEG 82, but on these servers a lower quality (median 60) would already match JPEG 82.
  • Imagick. libheif changes the quality scale together with the tuning, so file sizes stay about the same and AVIF 74 matches JPEG 82 even more often.
  • Plugin. On the newer libraries AVIF 70 still matches WebP 82 on most images (87% with GD, 86% with Imagick). With GD it is now about 3% larger than WebP 82, while with Imagick it stays 7% smaller.

So 74 stays a safe default with both the current and the newer libraries. The only cost on newer servers is a smaller saving with GD, not lower quality. Very few servers have the newer libraries today: no current Debian or Ubuntu LTS release ships libaom 3.13 together with libavif 1.4 or libheif 1.22.

Proposed fix

  • Plugin: pin the AVIF quality to 70 in webp_uploads_modify_webp_quality(), next to WebP 82 (#2746).
  • Core: add an AVIF default of 74 to WP_Image_Editor::get_default_quality() and wp_get_image_encode_quality(), so sites without the plugin get smaller AVIF files too (Trac ticket to follow).

GD and Imagick turn the quality number into the same compression setting, and the browser reads the same filter, so one value covers all three editors.

Related


🤖 Generated with Claude Code

Lingua principale
PHP
Stelle
467
Fork
171
Merge medio
13h 21m
PR unite (30g)
32

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di WordPress/performance

Tutte le issue di WordPress/performance

Issue simili

Altre issue su PHP

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.