Retour au blog

Guide du développeur pour servir des images en formats modernes

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.

Guide

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 type est obligatoire. Sans lui, le navigateur ne peut pas déterminer le support du format.
  • Incluez toujours width et height sur 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 sizes doit ê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-image en 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_files ou é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-image avec 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.

Convertir en WebP | Convertir en AVIF | Documentation API

Ready to optimize your images?

Start for free