Subito Labs

Utiliser les formats AVIF et Webp pour alléger votre site

Les formats d'images historiques que sont JPEG et PNG ont des successeurs, déjà supportés par les principaux navigateurs. Le WebP créé par Google et l'Avif promettent des poids ridicules et donc des gains de performances.

Moyennant quelques efforts, vous pouvez dès aujourd'hui les utiliser sur votre site et obtenir des scores lighthouse approchant les 100.

Voyons ensemble comment créer ces images et comment les intégrer à notre code.

Conversion aux formats WebP et Avif

Premièrement, il vous faut des images de base en jpeg ou png. Ensuite, si vous travaillez sur macOs, vous pouvez installer ces deux librairies :

brew install webp
brew install joedrago/repo/avifenc

Une fois installées, on peut compresser une image en webp, le flag -q pour "qualité" et -o pour "output":

cwebp -q 90 image.png -o image.webp

Pour l'Avif, vous pouvez voir les paramètres disponibles avec avifenc --help, pour l'exemple je compresse avec une qualité maximum de 63 :

avifenc --max 63 image.jpg image.avif

Le site Squoosh permet de convertir des images dans tous les formats communs, mais a l'inconvénient de traiter une image à la fois.

Dans votre HTML

C'est simple, tout comme la balise video, HTML5 nous offre la balise picture qui est un conteneur. A l'intérieur, vous déclarez dans l'ordre du plus léger au plus lourd les images en finissant par le format historique. Si votre navigateur ne supporte pas un format il passera au suivant :

<picture>
<source srcset="image.avif" type="image/avif">
<source srcset="image.webp" type="image/webp">
<img src="image.jpg" alt="">
</picture>

Dans votre CSS

C'est plus compliqué, il va nous falloir une classe pour savoir quand charger une background-image en avif/webp et quand retomber sur du jpeg/png.

On peut utiliser Modernizr mais il ne détecte pour l'instant que le webp.

Si vous préférez importer le moins de librairies tierces possible, voilà un petit snippet à ajouter à votre javascript. Il va tenter de créer des images et si elles ne sont pas supportées par votre navigateur, il ajoutera des classes à votre <body> :

// Avif/Webp detection
async function supportsEncode() {
const fallbackclass = 'old';
if (!this.createImageBitmap) return fallbackclass;

const avifData =
'data:image/avif;base64,AAAAFGZ0eXBhdmlmAAAAAG1pZjEAAACgbWV0YQAAAAAAAAAOcGl0bQAAAAAAAQAAAB5pbG9jAAAAAEQAAAEAAQAAAAEAAAC8AAAAGwAAACNpaW5mAAAAAAABAAAAFWluZmUCAAAAAAEAAGF2MDEAAAAARWlwcnAAAAAoaXBjbwAAABRpc3BlAAAAAAAAAAQAAAAEAAAADGF2MUOBAAAAAAAAFWlwbWEAAAAAAAAAAQABAgECAAAAI21kYXQSAAoIP8R8hAQ0BUAyDWeeUy0JG+QAACANEkA=',
webpData = 'data:image/webp;base64,UklGRiQAAABXRUJQVlA4IBgAAAAwAQCdASoCAAEAAQAcJaQAA3AA/v3AgAA=',
avifblob = await fetch(avifData).then((r) => r.blob()),
webpblob = await fetch(webpData).then((r) => r.blob());
return createImageBitmap(avifblob).then(
() => 'avif',
() => {
return createImageBitmap(webpblob).then(() => 'webp', () => fallbackclass)
}
)
};
// Add the supported format to the body's classList
(async () => {
const formatSupport = await supportsEncode();
document.body.classList.add(formatSupport);
})();

Maintenant vous pouvez ajouter des background-images dans votre CSS dans l'ordre du format le plus moderne au plus ancien :

.content       { background-image: url('img/background.avif'); }
.webp .content { background-image: url('img/background.webp'); }
.old .content { background-image: url('img/background.jpg'); }

Conclusion

C'est tout ce qu'il faut savoir, de nombreuses librairies et services permettent d'automatiser ce processus, notamment cloudinary et imagekit. Mais c'est suffisamment accessible pour que vous puissiez l'utiliser sur un petit projet.

Pour illustrer mon propos, voilà le poids total des images de ce site, par format :

  • jpeg/png: 26.5mo
  • avif: 7.1mo
  • webp: 4.1mo

Sur ces chiffres, je vous laisse aller convertir vos images... A bientôt !

Un projet à nous proposer ?

Contactez nous !