Vous savez que WebP et AVIF produisent des fichiers plus petits que le JPG. La question est comment les servir sans rien casser. La réponse implique l'élément <picture>, la négociation de contenu, les pipelines de build, et un peu de pragmatisme sur le moment où chaque approche est pertinente.
Ce guide est destiné aux développeurs qui veulent implémenter les formats modernes correctement, pas juste convertir quelques fichiers.
Le paysage des formats en 2026
| Format | Compression | Support navigateur | Adapté pour |
|---|---|---|---|
| JPEG | Avec perte, 8 bits | 100% | Fallback legacy, email, partage social |
| PNG | Sans perte, 8 bits, alpha | 100% | Graphiques, captures, transparence (quand WebP non viable) |
| WebP | Avec/sans perte, 8 bits, alpha, animation | 97% | Format web par défaut, pipelines dynamiques |
| AVIF | Avec/sans perte, 10/12 bits, alpha, HDR | 93% | Compression maximale, photographie, assets statiques |
La stack pratique en 2026 : AVIF en premier, fallback WebP, JPEG en dernier recours. Cela couvre 100% des navigateurs tout en offrant à 93% des utilisateurs la meilleure compression disponible.
Implémenter <picture> avec plusieurs sources
L'élément <picture> est la méthode standard pour servir plusieurs formats. Le navigateur évalue les éléments <source> de haut en bas et ne télécharge que le premier qu'il supporte :
<picture>
<source srcset="hero.avif" type="image/avif">
<source srcset="hero.webp" type="image/webp">
<img src="hero.jpg" alt="Description" width="1200" height="600">
</picture>
Combinez avec srcset pour les images responsive :
<picture>
<source
srcset="hero-400.avif 400w, hero-800.avif 800w, hero-1200.avif 1200w"
sizes="(max-width: 600px) 100vw, (max-width: 1200px) 80vw, 1200px"
type="image/avif">
<source
srcset="hero-400.webp 400w, hero-800.webp 800w, hero-1200.webp 1200w"
sizes="(max-width: 600px) 100vw, (max-width: 1200px) 80vw, 1200px"
type="image/webp">
<img
src="hero-800.jpg"
alt="Description"
width="1200"
height="600"
fetchpriority="high"
>
</picture>
Points essentiels :
- Listez AVIF avant WebP. Le navigateur prend le premier match.
- L'attribut
typeest obligatoire. Sans lui, le navigateur ne peut pas déterminer le support du format. - Incluez toujours
widthetheightsur le<img>pour éviter le layout shift (CLS). - Utilisez
fetchpriority="high"sur l'image LCP,loading="lazy"sur les images sous le fold. - L'attribut
sizesdoit être identique sur tous les<source>et le<img>.
Négociation de contenu côté serveur via le header Accept
La négociation de contenu sert le bon format depuis une URL unique. Le navigateur envoie un header Accept listant les formats qu'il supporte, et le serveur répond avec le meilleur match.
Un navigateur moderne typique envoie :
Accept: image/avif, image/webp, image/png, image/jpeg, */*
Configuration Nginx :
map $http_accept $webp_suffix {
default "";
"~*image/webp" ".webp";
}
map $http_accept $avif_suffix {
default "";
"~*image/avif" ".avif";
}
location ~* \.(jpg|jpeg|png)$ {
# Essayer AVIF d'abord, puis WebP, puis l'original
try_files $uri$avif_suffix $uri$webp_suffix $uri =404;
add_header Vary Accept;
}
Important : retournez toujours Vary: Accept quand la réponse dépend du header Accept. Sans cela, les caches et CDN peuvent servir le mauvais format au mauvais navigateur.
Avantages de la négociation de contenu :
- HTML plus simple, une seule balise
<img>. - Fonctionne avec
background-imageen CSS. - Aucun JavaScript côté client nécessaire.
Inconvénients :
- Nécessite une configuration serveur.
- Plus difficile à débugger (la même URL retourne un contenu différent).
- Ne fonctionne pas avec l'hébergement statique qui ne supporte pas
try_filesou équivalent.
Négociation de format au niveau CDN
La plupart des CDN modernes supportent la négociation automatique de format d'image, combinant les avantages de la négociation de contenu sans nécessiter de changement sur le serveur d'origine :
Cloudflare : Polish + conversion WebP/AVIF dans le tableau de bord Cloudflare. Activé par zone, aucun changement de code nécessaire. Cloudflare lit le header Accept et sert le format approprié depuis son cache.
AWS CloudFront + Lambda@Edge : écrivez une fonction Lambda qui réécrit l'URI de la requête en fonction du header Accept, pointant vers des variantes AVIF/WebP pré-générées sur S3.
Fastly : utilisez VCL pour inspecter req.http.Accept et modifier req.url ou définir une clé de variation de cache.
La négociation au niveau CDN est l'approche la moins coûteuse en effort pour les sites existants. L'origine sert du JPEG, le CDN convertit ou sélectionne la bonne variante, et le client reçoit de l'AVIF ou du WebP automatiquement.
Intégration dans le pipeline de build
Pour les sites statiques et les workflows avec étape de build, générez toutes les variantes de format au moment du build :
Avec l'API Morphix dans un script de build :
#!/bin/bash
for file in src/images/*.{jpg,jpeg,png}; do
[ -f "$file" ] || continue
name=$(basename "${file%.*}")
for format in webp avif; do
curl -s -X POST https://morphix.tools/api/v1/convert \
-H "Authorization: Bearer $MORPHIX_API_KEY" \
-F "file=@$file" \
-F "format=$format" \
-F "quality=80" \
--output "dist/images/$name.$format"
done
cp "$file" "dist/images/"
done
Cela produit trois fichiers par image source : original, WebP et AVIF. Votre template HTML utilise ensuite <picture> pour référencer les trois.
Intégration framework :
- Next.js : le composant
<Image>intégré gère la négociation WebP/AVIF automatiquement via son API d'optimisation d'images. - Astro : le composant
<Image>génère les formats optimisés au moment du build. - Gatsby :
gatsby-plugin-imageavec Sharp génère les variantes WebP automatiquement. - HTML statique : utilisez un script de build comme montré ci-dessus, ou un task runner comme Make.
Tests et validation
Après l'implémentation, validez que le bon format est servi :
DevTools du navigateur. Ouvrez l'onglet Network, chargez la page, et vérifiez le header Content-Type de chaque réponse image. Il doit afficher image/avif, image/webp ou image/jpeg selon votre navigateur et votre configuration.
Testez avec différents navigateurs. Si vous utilisez la négociation de contenu, testez avec un navigateur qui ne supporte pas l'AVIF (ou désactivez temporairement le support AVIF dans les DevTools) pour vérifier que le fallback WebP fonctionne.
Vérifiez Vary: Accept. Si vous utilisez la négociation côté serveur, vérifiez que le header Vary: Accept est présent. Sans lui, les caches CDN peuvent servir de l'AVIF à un navigateur qui ne supporte que le JPEG.
Lighthouse. Lancez Lighthouse et vérifiez l'audit "Serve images in next-gen formats". Il doit passer si vous servez du WebP ou de l'AVIF.
Comparaison visuelle. Ouvrez la même page avec et sans conversion de format et comparez la qualité visuelle. À qualité 80, la différence doit être invisible.
Convertissez vos images
Morphix convertit vos images JPG et PNG en WebP et AVIF directement dans le navigateur, ou à grande échelle via l'API. Aucune inscription requise avec l'offre gratuite.