Images WebP/AVIF WordPress qui ne s’affichent pas : causes principales et configuration correcte
décembre 18, 2025 • février 3, 2026 • Lecture : 12 min • Views: 6
Cet article vous a aidé ?
Tout semble correct dans la bibliothèque de médias. Votre thème n’a pas changé. Le HTML de la page contient des <img>. Et pourtant — des carrés vides, des vignettes cassées ou « l’image ne peut pas être affichée car elle contient des erreurs ».
Ceci est le motif d’échec WebP/AVIF : l’image existe, l’URL résout, et le navigateur refuse quand même de l’afficher. La cause n’est généralement pas « WordPress ». C’est une chaîne de petites décisions de configuration : types MIME, clés de cache, négociation de contenu, outils de conversion, et un plugin qui a un peu trop pris confiance.
Guide de diagnostic rapide
Si vous avez cinq minutes avant qu’un responsable n’annonce un « incident majeur », faites ceci dans l’ordre. L’objectif est de trouver rapidement le goulot d’étranglement : est-ce le navigateur qui refuse les octets, le serveur qui renvoie des en-têtes erronés, ou un CDN qui met en cache la mauvaise variante ?
Première étape : confirmer ce que le navigateur reçoit
Ouvrez DevTools → Network → cliquez sur la requête d’image échouée.
Vérifiez le Status (200/304/403/404/500), le Content-Type, le Content-Length, et tout message d’erreur comme « CORB », « MIME type mismatch », ou « Failed to decode image ».
Regardez le corps de la Response : est-ce réellement une image, ou du HTML (comme une page 403, une page de connexion, ou un blocage WAF) ?
Deuxième étape : reproduire avec curl depuis un point de vue propre
Récupérez l’URL avec les en-têtes : confirmez Content-Type: image/webp ou image/avif, pas text/html.
Essayez avec et sans en-têtes Accept pour attraper une négociation de contenu cassée.
Comparez la réponse du CDN edge et celle de l’origine.
Troisième étape : vérifier les clés de cache et la logique des variantes
Le CDN varie-t-il le cache en fonction de Accept ? Sinon, une requête malchanceuse peut empoisonner le cache (WebP servi à un client non-WebP, ou inversement).
Un plugin WordPress réécrit-il les URLs vers .webp/.avif sans s’assurer que les fichiers existent ?
Le serveur envoie-t-il le mauvais Content-Type pour .webp/.avif ?
Quatrième étape : ne touchez WordPress qu’ensuite
Inspectez le HTML généré : src, srcset, ordre des picture/source.
Vérifiez les plugins qui font la conversion, le lazy-load, l’offload CDN, et le cache/minify. Désactivez-les un par un.
Vérifiez que les fichiers existent là où WordPress pense qu’ils sont (wp-content/uploads ou stockage externalisé).
Ce qui casse réellement quand WebP/AVIF ne s’affichent pas
Les navigateurs tolèrent beaucoup de choses. Le décodage d’image n’en fait pas partie. Quand une image « ne s’affiche pas », c’est généralement l’une des quatre catégories suivantes :
Mauvais octets : l’URL se termine par .webp mais renvoie des octets JPEG (ou du HTML). Certains navigateurs essaient, la plupart refusent.
Mauvais en-têtes : octets corrects, mais Content-Type incorrect (comme text/plain) qui déclenche un comportement strict ou casse des intermédiaires.
Mauvaise variante : le CDN met en cache une réponse AVIF et la sert à un client qui ne supporte que WebP/JPEG, parce que la clé de cache a ignoré Accept.
Mauvais HTML : votre balisage pointe directement vers .avif sans fallback, ou le plugin a mal généré le srcset.
Il y a aussi une « cinquième catégorie » : vous avez un WAF ou une protection hotlink qui bloque les requêtes sans Referer, et maintenant votre plugin d’optimisation récupère des images d’une manière qui déclenche la règle. Les produits de sécurité aiment être utiles comme ça.
Une citation à garder sur un post-it, car elle s’applique à tous ces échecs : « L’espoir n’est pas une stratégie. » — Vernon Sanders, souvent cité dans les cercles d’exploitation (idée paraphrasée). Vous n’allez pas vous en sortir en devinant ; vous allez observer et confirmer.
Faits et courte histoire utiles pour le débogage
Ce ne sont pas des anecdotes pour un quiz au bar. Elles expliquent pourquoi votre stack se comporte ainsi.
WebP a été publié par Google en 2010 comme format dérivé de VP8 ; les lacunes de support initiales ont créé des années d’hypothèses « ça marche sur Chrome ».
AVIF est basé sur AV1 (le codec vidéo). Les images fixes héritent de l’efficacité de compression et de la complexité d’AV1, ce qui a un impact sur le CPU et le temps de conversion.
Le support WebP de Safari est arrivé tard (Safari 14). Beaucoup de configurations WordPress héritées gardent des contournements « si Safari alors JPEG » comme des mines terrestres anciennes.
Le support AVIF est plus récent et fragmenté ; certains navigateurs le supportent, certains appareils ont des décodeurs partiels ou bogués, et certains environnements d’entreprise figent les versions de navigateur.
Servir des formats modernes se fait souvent via négociation de contenu avec l’en-tête Accept, ce qui casse spectaculairement si les caches ne varient pas correctement.
WordPress a historiquement restreint les types MIME uploadés ; les versions modernes supportent WebP, mais les bibliothèques côté serveur (GD/Imagick) peuvent ne pas le faire.
Les CDN peuvent « aider » en convertissant automatiquement les images, mais cela peut entrer en conflit avec des plugins WordPress qui font la même tâche, entraînant une double optimisation ou des variantes incorrectes.
AVIF peut être plus petit que WebP, mais plus lent à encoder. Les équipes découvrent souvent cela pendant une fenêtre de déploiement. Un mauvais timing est aussi un format.
Beaucoup d’incidents d’images cassées sont en réalité des erreurs HTML servies avec un statut 200 ; le navigateur récupère « une image » et obtient une page de connexion.
Blague #1 : WebP n’est pas « à l’épreuve du web ». Si c’était le cas, nous ne serions pas ici, et j’écrirais sur quelque chose de relaxant — comme le BGP.
Modes de panne : navigateur, serveur, CDN, WordPress
1) Échec côté navigateur : erreur de décodage ou format non supporté
Si vous encodez en dur .avif dans <img src> sans fallback, un navigateur non-AVIF ne rétrogradera pas poliment. Il n’affichera rien. Le schéma correct est <picture> avec des <source type> ordonnés, puis un <img> fallback final.
Un autre échec côté navigateur : fichiers corrompus. Cela se produit quand la conversion a été interrompue, ou quand un plugin a écrit une sortie partielle tout en ayant mis à jour les métadonnées.
Servir WebP/AVIF n’est pas difficile, mais il est facile de se tromper de manière qui semble correcte au premier abord.
Type MIME manquant : le serveur renvoie application/octet-stream ou text/plain. Certains navigateurs rendent encore ; certains intermédiaires non.
Règles de réécriture trop futées : vous réécrivez .jpg vers .webp inconditionnellement. Si le .webp n’existe pas, vous aurez des 404 sur l’ensemble du site.
Handler de fichiers statiques vs PHP : un bloc location mal configuré envoie .webp via PHP (lent) ou le bloque via des règles de sécurité.
3) Échec CDN : empoisonnement du cache par mauvais appariement de variante
C’est le gros problème. Votre origine fait le bon travail : si Accept contient image/avif, elle sert AVIF ; sinon WebP ; sinon JPEG. Puis votre CDN met en cache la première réponse qu’il voit sous une clé basée sur l’URL seulement. Le client suivant reçoit l’AVIF mis en cache même s’il ne supporte pas AVIF. Boom : images cassées, mais seulement pour certains utilisateurs, et seulement parfois. Parfait pour gaspiller des après-midis.
4) Échec WordPress : plugins qui réécrivent les URLs et métadonnées
WordPress ne gère pas nativement une négociation complète pour les formats modernes. La plupart des sites s’appuient sur un plugin ou une fonctionnalité CDN. Les plugins varient grandement en qualité. Points de casse courants :
Ils génèrent .webp/.avif mais ne mettent pas à jour correctement le srcset.
Ils mettent à jour les références en base mais n’arrivent pas à régénérer les vignettes.
Ils ne respectent pas le stockage offload (S3-compatible) et génèrent des chemins locaux qui n’existeront jamais.
Ils entrent en conflit avec des plugins de cache/minify qui réécrivent le HTML après coup.
Tâches pratiques (commandes, sorties, décisions)
Voici des vérifications réelles que vous pouvez exécuter. Chacune inclut : une commande, la sortie qui compte, et quelle décision prendre ensuite. Exécutez-les depuis un shell serveur (ou votre laptop pour les vérifications curl). Ne « changez pas les choses pour voir si ça aide ». Observez d’abord.
Tâche 1 : Confirmer que l’URL défaillante renvoie une vraie image (pas du HTML)
Ce que cela signifie : le statut est 200 et content-type correspond à AVIF. Bon signe.
Décision : si content-type est text/html ou si le fichier est minuscule (1–5 KB), ouvrez le body : vous obtenez probablement une page d’erreur, un blocage WAF, ou une chaîne de redirections.
Tâche 2 : Identifier le type de fichier par les magic bytes (ne pas faire confiance aux extensions)
cr0x@server:~$ file -b /tmp/img.bin
ISO Media, AVIF Image
Ce que cela signifie : les octets sont réellement AVIF.
Décision : s’il est indiqué « HTML document » ou « JPEG image data », vous avez une confusion rewrite/CDN/origine. Corrigez cela avant de toucher à WordPress.
Tâche 3 : Vérifier ce qui se passe pour des clients sans support AVIF/WebP
Ce que cela signifie : le serveur négocie et renvoie du JPEG, et il définit Vary: Accept. C’est ce que vous voulez.
Décision : s’il n’y a pas de Vary: Accept, votre CDN peut mettre en cache la mauvaise variante à moins que vous ne le configuriez explicitement. Ajoutez Vary et assurez-vous que le CDN le respecte (ou utilisez des URLs séparées par format).
Tâche 4 : Comparer les en-têtes de l’edge CDN et de l’origine
Ce que cela signifie : le CDN sert AVIF depuis le cache (HIT), et Vary est présent.
Décision : si la réponse edge diffère de l’origine (mauvais content-type, vary manquant), purgez le CDN et corrigez la gestion des clés de cache / vary. Ne faites pas de purge comme style de vie.
Tâche 5 : Valider que nginx connaît les types MIME WebP/AVIF
Ce que cela signifie : Apache a les modules nécessaires pour AddType et Header.
Décision : si mime_module est absent, Apache peut mal servir les types inconnus. Activez-le, puis définissez AddType image/webp .webp et AddType image/avif .avif.
Tâche 7 : Vérifier si le serveur compresse accidentellement les images avec gzip
Ce que cela signifie : pas de Content-Encoding: gzip (bon). Compresser des formats déjà compressés est inutile et parfois nuisible avec des intermédiaires bogués.
Décision : si vous voyez content-encoding: gzip pour des images, corrigez vos règles de compression pour exclure image/* (surtout WebP/AVIF).
Tâche 8 : Confirmer que le fichier existe sur le disque (vérification d’origine)
cr0x@server:~$ sudo ls -lh /var/www/html/wp-content/uploads/2025/11/hero.avif
-rw-r--r-- 1 www-data www-data 48K Nov 20 09:14 /var/www/html/wp-content/uploads/2025/11/hero.avif
Ce que cela signifie : l’origine possède le fichier, les permissions semblent normales.
Décision : s’il manque, le plugin ne l’a jamais généré, ou vous avez externalisé les médias et oublié que le système de fichiers de l’origine n’est plus la source de vérité.
Tâche 9 : Détecter des conversions partielles/corrompues avec ffmpeg ou avifdec
Ce que cela signifie : aucune sortie indique que ffmpeg a pu parser et décoder sans erreurs.
Décision : si vous voyez des erreurs de décodage, régénérez cet asset et investiguez votre chaîne d’outils de conversion (CPU/mémoire/timeouts).
Tâche 10 : Vérifier que WordPress considère les métadonnées de l’attachement comme correctes
cr0x@server:~$ wp post meta get 123 _wp_attachment_metadata --format=json | head -c 220; echo
{"width":2400,"height":1600,"file":"2025/11/hero.jpg","sizes":{"thumbnail":{"file":"hero-150x150.jpg","width":150,"height":150,"mime-type":"image/jpeg"}...
Ce que cela signifie : les métadonnées WordPress référencent le JPEG original et ses tailles dérivées. Beaucoup de plugins stockent WebP/AVIF séparément.
Décision : si les métadonnées pointent vers .webp/.avif mais que les fichiers n’existent pas (ou inversement), vous avez un décalage. Régénérez les vignettes et relancez le « bulk optimize » du plugin avec les bons réglages.
Tâche 11 : Inspecter le HTML rendu pour picture, srcset et l’ordre
Ce que cela signifie : c’est correct : AVIF d’abord, WebP ensuite, JPEG en fallback.
Décision : si vous voyez <img src="...avif"> sans fallback, corrigez le thème/plugin. Si type est erroné ou manquant, certains navigateurs ne sélectionneront pas la source.
Tâche 12 : Attraper « bloqué par WAF/hotlink protection » qui se fait passer pour des images
Ce que cela signifie : 403 avec un body HTML. Le navigateur a demandé une image et a reçu une page de refus.
Décision : ajustez les règles WAF, la protection hotlink, ou la logique d’URL signée pour que les requêtes légitimes d’images soient autorisées. Assurez-vous aussi que votre optimiseur d’images ne récupère pas les images avec des en-têtes étranges qui déclenchent des blocs.
Tâche 13 : Vérifier que CDN/origine renvoient un bon Content-Length et supportent les requêtes range
Ce que cela signifie : les requêtes Range fonctionnent. Cela compte pour certains clients, intermédiaires, et comportements de performance.
Décision : si les ranges échouent et que votre CDN les attend, vous pouvez obtenir des chargements partiels ou des comportements clients étranges. Corrigez la gestion des fichiers statiques et les paramètres de proxy du serveur.
Tâche 14 : Confirmer le support de conversion d’images dans les bibliothèques PHP (GD/Imagick)
cr0x@server:~$ php -r 'print_r(function_exists("gd_info")?gd_info():["gd"=>"missing"]);' | egrep -i 'WebP Support|AVIF Support|JPEG Support'
WebP Support => 1
AVIF Support => 0
JPEG Support => 1
Ce que cela signifie : GD peut écrire WebP mais pas AVIF. Beaucoup de plugins WordPress chutent silencieusement ou ne génèrent que certains formats.
Décision : si vous avez besoin d’AVIF, utilisez un convertisseur qui le supporte (souvent via Imagick avec libheif, ou des outils externes), ou déléguez la conversion au CDN et conservez l’origine en JPEG/PNG/WebP.
Tâche 15 : Vérifier le support des codecs dans Imagick
Ce que cela signifie : Imagick supporte AVIF et WebP sur cet hôte. C’est assez rare pour le célébrer discrètement.
Décision : si AVIF manque, vous pouvez installer/compilier Imagick avec le support libheif, ou arrêter de promettre AVIF depuis l’origine et n’utiliser que WebP + fallback JPEG.
Tâche 16 : Chercher des règles de réécriture qui forcent .webp même quand il est absent
Vous voulez des formats modernes sans drame moderne. Voici la configuration qui survit au trafic, aux CDN et aux mises à jour de plugins.
Principe 1 : Préférez <picture> à la réécriture d’URL
Si vous pouvez contrôler la génération du markup (niveau thème ou via un plugin bien conçu), utilisez :
<source type="image/avif"> en premier
<source type="image/webp"> en second
<img src="...jpg/png"> en fallback
Cela évite la complexité des clés de cache parce que les différents formats peuvent avoir des URLs différentes. Ce n’est pas aussi « malin », et c’est le but.
Principe 2 : Si vous faites de la négociation de contenu, traitez le cache comme une fonctionnalité de première classe
La négociation de contenu signifie même URL, octets différents. Cela ne fonctionne que lorsque :
L’origine envoie Vary: Accept
Le CDN met en cache séparément par Accept (ou vous configurez des clés de cache séparées)
Vous avez une stratégie de purge quand vous changez les paramètres de conversion
Sans cela, la négociation devient une « loterie d’images aléatoire ».
Principe 3 : N’exigez pas AVIF si vous ne pouvez pas le produire de façon fiable
AVIF est excellent. C’est aussi un peu capricieux en environnement serveur : il vous faut les bonnes bibliothèques, et la conversion coûte cher en CPU. Si vous ne pouvez pas garantir l’achèvement des conversions et les en-têtes corrects, utilisez d’abord WebP et considérez AVIF comme optionnel.
Si vous devez mapper JPEG/PNG vers WebP quand disponible, faites-le avec try_files, pas une réécriture inconditionnelle. Exemple (conceptuel ; adaptez soigneusement vos chemins) :
cr0x@server:~$ sudo nginx -T 2>/dev/null | sed -n '180,260p'
location ~* \.(png|jpe?g)$ {
add_header Vary Accept;
set $webp_suffix "";
if ($http_accept ~* "image/webp") {
set $webp_suffix ".webp";
}
try_files $uri$webp_suffix $uri =404;
}
Pourquoi cela fonctionne : il ne sert .webp que s’il existe. Sinon il sert l’original. Pas d’averses de 404.
Configuration WordPress : décider qui gère la conversion
Vous avez trois modèles de responsabilité viables. Choisissez-en un et engagez-vous. Les mélanger crée des bugs fantômes.
Le plugin gère la conversion, l’origine sert les formats modernes statiques : le plus courant. Fonctionne si votre serveur dispose des bibliothèques et que vous gérez l’invalidation du cache.
Le CDN gère la conversion : l’origine stocke JPEG/PNG, le CDN sert WebP/AVIF aux clients capables. Moins de charge sur vos serveurs, moins de problèmes de bibliothèques. Nécessite une discipline de configuration du CDN.
Le pipeline de build gère la conversion : vous convertissez les images avant l’upload/déploiement. Idéal pour sites de marque et workflows médias contrôlés, moins indiqué pour du contenu généré par les utilisateurs.
Choisissez une stratégie de fallback et testez-la comme si la production en dépendait (car c’est le cas)
Comportement minimum acceptable :
Tout client reçoit une image (JPEG/PNG au pire).
Aucun plugin ne doit remplacer l’unique URL par une URL AVIF sans fallback.
Une conversion cassée ne doit pas casser les pages existantes (servir l’ancien format pendant que le nouveau est en traitement).
Blague #2 : La seule chose « sans perte » dans l’optimisation d’images est votre patience quand la clé de cache ignore Accept.
Erreurs communes (symptômes → cause profonde → correction)
1) Symptomatique : images cassées uniquement sur Safari ou appareils plus anciens
Cause profonde : vous servez AVIF (ou WebP) sans fallback, ou le CDN a mis en cache AVIF et le sert à tout le monde.
Correction : utilisez <picture> avec fallback JPEG, ou assurez-vous de Vary: Accept et que la clé de cache CDN varie selon Accept. Purgez après modifications.
2) Symptomatique : DevTools affiche 200 OK mais l’image est vide
Cause profonde : le corps de la réponse n’est pas une image (page de refus HTML, blocage WAF, ou « soft 404 ») servi avec 200 ou 403.
Correction : récupérez avec curl et inspectez Content-Type et les magic bytes. Corrigez WAF/protection hotlink ; assurez-vous que les chemins statiques contournent l’auth et les challenges de sécurité.
3) Symptomatique : certains utilisateurs voient les images, d’autres voient des icônes cassées ; vider les caches « règle » temporairement
Cause profonde : empoisonnement du cache CDN dû à l’absence de vary/clé de cache correcte. La première requête impose sa variante.
Correction : configurez le CDN pour varier selon Accept (ou utilisez des URLs séparées par format). Assurez-vous que l’origine définit Vary: Accept. Purgez les chemins affectés.
4) Symptomatique : 404 pour les URLs .webp après activation d’un plugin d’optimisation
Cause profonde : le plugin a réécrit les URLs d’images vers .webp mais n’a pas généré ces fichiers (ou a échoué en cours de lot).
Correction : désactivez la réécriture d’URL, lancez la génération en lot, confirmez les cibles filesystem/offload, puis réactivez. Ajoutez un fallback try_files côté serveur si vous insistez sur la réécriture.
5) Symptomatique : les images se téléchargent au lieu de s’afficher
Cause profonde : mauvais Content-Type, parfois application/octet-stream.
Correction : ajoutez les types MIME corrects dans nginx/Apache. Retestez les en-têtes. Certains CDN nécessitent aussi un mappage explicite des types.
6) Symptomatique : les vignettes sont cassées mais les images originales chargent
Cause profonde : les tailles dérivées n’ont pas été converties/régénérées ; le srcset pointe vers des variantes inexistantes.
Correction : régénérez les vignettes ; relancez le convertisseur pour toutes les tailles ; vérifiez les métadonnées pour un échantillon d’attachements.
7) Symptomatique : pics CPU élevés lors de l’activation d’AVIF ; pages en timeout
Cause profonde : la conversion s’exécute à la volée dans les requêtes, ou les jobs de lot affament l’hôte. L’encodage AVIF est coûteux.
Correction : faites la conversion hors chemin de requête avec des limites ; utilisez des workers en file d’attente ; ou laissez le CDN faire la conversion. Imposer des limites de concurrence strictes sur les encodages.
8) Symptomatique : seuls les admins voient les images correctes ; les utilisateurs non connectés non
Cause profonde : le cache varie selon les cookies/auth, ou le plugin d’optimisation évite la conversion pour les utilisateurs connectés, ou le CDN sert des variantes différentes.
Correction : comparez les réponses avec/sans cookies. Corrigez les règles de cache et assurez-vous que la même URL résout vers l’asset correct pour le trafic anonyme.
Listes de vérification / plan pas à pas
Plan pas à pas : atteindre une base correcte (sans exploits)
Choisir la responsabilité : plugin, CDN, ou pipeline de build. Ne lancez pas deux convertisseurs.
Établir le HTML de fallback : privilégiez <picture> avec fallback JPEG/PNG.
Corriger les types MIME : assurez-vous que image/webp et image/avif sont corrects à l’origine et au CDN.
Confirmer que les octets correspondent aux en-têtes :file contre le contenu téléchargé ; pas de pages d’erreur HTML.
Corriger la variation de cache : si vous négociez par Accept, vous devez utiliser Vary: Accept et la variation de clé CDN.
Régénérer les dérivés : les vignettes et tailles responsive sont où la casse silencieuse se cache.
Tester la charge du workflow de conversion : les encodages AVIF peuvent saturer le CPU. Planifiez où la chaleur va.
Mettre en place une surveillance : suivez les taux 404/403 sur .webp/.avif, suivez les mismatches de Content-Type si possible.
Checklist de release pour activer AVIF/WebP en production
Au moins trois profils de navigateurs testés : AVIF-capable, WebP-seulement, et aucun des deux (test d’en-tête Accept forcé fonctionne).
Clé de cache CDN vérifiée pour le comportement des variantes, ou utilisation d’URLs séparées par format.
L’origine renvoie les bons types MIME et ne gzippe pas les images.
Les jobs de conversion sont hors du chemin des requêtes ou strictement limités.
Plan de rollback : désactiver la réécriture/négociation sans casser les URLs d’images.
Quand quelque chose casse : checklist de confinement
Arrêter l’hémorragie : désactivez la réécriture d’URL qui force .avif/.webp si les fichiers ne sont pas garantis.
Purgez le cache CDN pour les chemins affectés seulement (ne pas tout purger sauf si vous aimez les pannes auto-infligées).
Revenir au fallback JPEG/PNG dans le markup si votre thème/plugin le supporte.
Confirmez que les réponses 200 sont de vraies images (pas du HTML).
Trois mini-récits d’entreprise du terrain
Mini-récit 1 : L’incident causé par une mauvaise hypothèse
Un site e-commerce de taille moyenne voulait « des images modernes partout ». Le plan semblait propre : activer la conversion AVIF dans le plugin d’optimisation, activer les réécritures nginx pour que .jpg devienne .avif pour les navigateurs compatibles, puis laisser le CDN faire son travail habituel.
Quelqu’un a supposé que le CDN variait automatiquement le cache selon Accept. Il ne l’a pas fait, du moins pas pour cette règle de cache. La première requête après le déploiement provenait d’un client Chrome qui annonçait le support AVIF. Le CDN a mis en cache la réponse AVIF sous l’URL JPEG.
La vague suivante de trafic comprenait des navigateurs embarqués dans des applications mobiles et des appareils plus anciens. Ils ont demandé la même URL JPEG, ont reçu des octets AVIF, et n’ont pas pu décoder. Le tableau d’incidents montrait « échecs de chargement d’images » mais la santé de l’origine était verte. Car bien sûr elle l’était.
La correction n’a pas été magique : configurer correctement la variation du cache (ou arrêter de négocier sur la même URL), purger les objets empoisonnés, et ajouter un test qui curl une série d’URLs d’images représentatives avec différents en-têtes Accept avant chaque rollout. La leçon n’était pas « ne pas utiliser AVIF ». C’était « ne déléguez pas vos hypothèses à un cache ».
Mini-récit 2 : L’optimisation qui a foiré
Une plateforme de communication interne avait grandi au point où le stockage média était devenu un poste budgétaire concret. Quelqu’un a proposé AVIF agressif pour tout, avec conversion à la demande : quand un utilisateur voit une page, le serveur convertit les variantes AVIF manquantes et les met en cache. Ça « étalerait le travail ».
Ça a étalé le travail. Malheureusement, ça l’a étalé sur la couche web pendant le pic de trafic. La librairie de conversion était gourmande en CPU. Les requêtes se sont mises en file. Les workers PHP ont été bloqués en attendant des conversions et des écritures disque. La latence a augmenté, puis les timeouts, puis la couche cache a commencé à retenter en amont, ce qui n’est jamais une histoire d’amour.
Pire, quelques conversions ont été interrompues. Des fichiers partiels ont été écrits, mais la mise à jour des métadonnées a réussi. Certains utilisateurs ont reçu des AVIF corrompus servis avec un Content-Type correct. Ce sont les échecs les plus irritants car tout semble « correct » jusqu’à décodage.
Le rollback a été simple : arrêter la conversion à la demande, déplacer la conversion vers une file contrôlée avec limites de concurrence, et servir WebP/JPEG tant que les variantes ne sont pas prêtes. Les économies de disque sont revenues, et le système a cessé d’essayer de se mettre en feu pour économiser quelques kilo-octets.
Mini-récit 3 : La pratique ennuyeuse qui a sauvé la mise
Une maison d’édition gérait plusieurs propriétés WordPress derrière le même CDN. Ils avaient une règle qui semblait douloureusement peu sexy : chaque nouveau type d’asset obtient un « test de contrat d’en-têtes » dans la CI. Il vérifie les codes de statut, Content-Type, Cache-Control, et le comportement des variantes avec différents Accept headers.
Quand ils ont ajouté WebP puis AVIF, ils n’ont pas juste coché le toggle du plugin et prié. Ils ont déployé sur un domaine de staging qui utilisait la même config CDN que la production. Le job CI récupérait un ensemble d’images canoniques via le CDN et directement depuis l’origine, comparait les en-têtes, et échouait si elles divergeaient.
Au premier essai AVIF, le test a échoué : le CDN avait supprimé Vary: Accept sur une règle de cache par chemin. Personne ne l’avait remarqué en test manuel parce que leurs navigateurs étaient modernes. Le test l’a remarqué, car il forçait un en-tête Accept excluant AVIF et attendait un fallback JPEG.
Ils ont corrigé la règle CDN avant que les utilisateurs ne le voient. Rien n’a explosé. Personne n’a été réveillé. C’est ce que l’« ennuyeux » vous achète : du sommeil et de la crédibilité.
FAQ
1) Dois-je servir AVIF, WebP, ou les deux ?
Les deux, si vous pouvez le faire de façon fiable. AVIF d’abord pour les clients supportés, WebP ensuite, fallback JPEG/PNG en dernier recours. Si votre serveur ne peut pas encoder AVIF de manière fiable, servez WebP + JPEG et laissez AVIF en option (côté CDN est un compromis courant).
2) Pourquoi j’obtiens 200 OK mais l’image ne s’affiche toujours pas ?
Parce que « 200 » n’est pas une promesse que les octets sont une image. Vérifiez Content-Type et inspectez le corps. Une page de connexion 200 servie à une URL d’image restera une image cassée.
3) Dois-je ajouter des types MIME pour WebP et AVIF ?
Oui. Beaucoup de serveurs ne devinent pas correctement. Vous voulez image/webp et image/avif. Des types MIME erronés peuvent provoquer des téléchargements, des rendus bloqués ou un comportement CDN étrange.
4) Puis-je me fier uniquement à un plugin WordPress ?
Vous le pouvez, mais vérifiez toute la chaîne : support des outils de conversion (GD/Imagick), régénération des vignettes, et comment le plugin réécrit le HTML/les URLs. Les plugins fonctionnent souvent parfaitement jusqu’à ce que vous ajoutiez un CDN, l’externalisation des médias, ou un autre plugin « utile ».
5) Quelle est la manière la plus sûre d’implémenter des formats modernes sur WordPress ?
Utilisez le balisage <picture> et des URLs distinctes par format. Cela évite la complexité de variation de cache. Si vous avez besoin de négociation, considérez Vary: Accept et les clés de cache comme des exigences non négociables.
6) Mon CDN dit qu’il supporte WebP/AVIF automatiquement. Pourquoi les images sont-elles cassées ?
Parce que « supporte » peut vouloir dire « peut convertir », pas « variera le cache correctement pour vos règles ». Confirmez le comportement de la clé de cache, confirmez Vary: Accept, et vérifiez si votre origine fait déjà la conversion — la double conversion et la confusion de variantes sont courantes.
7) Pourquoi seules les vignettes cassent ?
Parce que les vignettes sont des fichiers séparés. Votre original a peut-être été converti, mais les tailles dérivées utilisées par srcset n’ont pas été générées ou ont été générées à un emplacement différent (surtout avec un offload média).
8) AVIF est-il toujours plus petit que WebP ?
Souvent, mais pas toujours. Le contenu compte. AVIF peut être excellent pour les photographies, mais il peut être plus lent à encoder et parfois ne vaut pas la peine pour de petites icônes UI. Mesurez ; ne supposez pas.
9) Pourquoi l’activation d’AVIF a provoqué un pic CPU et ralenti le site ?
Parce que l’encodage est coûteux. Si les conversions se font dans la requête, vous avez mis une charge de type codec vidéo sur votre couche web. Déplacez la conversion en tâches de fond, limitez la concurrence, ou externalisez la conversion au CDN.
10) Dois-je purger les caches après avoir activé WebP/AVIF ?
Généralement oui — surtout si vous avez modifié la réécriture d’URL, les règles de négociation, ou le comportement du CDN. Sinon vous risquez de servir des variantes obsolètes, ou de garder un objet de cache empoisonné plus longtemps que votre patience.
Prochaines étapes à faire dès aujourd’hui
Si les images WebP/AVIF ne s’affichent pas, ne commencez pas par réinstaller des plugins. Commencez par confirmer quels octets sont servis, avec quels en-têtes, et qui les met en cache.
Choisissez une URL d’image cassée et exécutez les vérifications curl + file. Confirmez : statut, Content-Type, et magic bytes sont cohérents.
Si vous utilisez la négociation de contenu, vérifiez Vary: Accept et le comportement de clé de cache CDN. Si vous ne pouvez pas garantir cela, passez à <picture> avec des URLs séparées par format.
Confirmez les types MIME serveur pour .webp et .avif. Corrigez-les à l’origine ; ne comptez pas sur « le CDN qui s’en chargera ».
Auditez vos plugins WordPress : un seul convertisseur, un seul réécrivain HTML, un seul plugin de cache (ou au moins, un qui ait la responsabilité). Tout le reste n’est qu’un concours de celui qui casse le markup en dernier.
Régénérez les vignettes et validez le srcset pour quelques attachements représentatifs.
Les formats modernes en valent la peine. Ne les implémentez pas comme un tour de magie. Faites-le comme un opérateur : comportement observable, fallback sûrs, et caches configurés — pas espérés.