Chargement d'image Web le plus optimisé en 2021



Dans cet article, je partagerai 8 techniques pour optimiser le chargement des images qui réduisent la bande passante réseau requise et la charge du processeur lorsqu'elles sont affichées à l'écran. Voici quelques exemples de HTML annoté pour vous faciliter la reproduction. Certaines techniques sont connues depuis longtemps et certaines sont apparues relativement récemment. Idéalement, votre mécanisme de publication de documents Web préféré (tel qu'un CMS, un générateur de site statique ou un cadre d'application Web) devrait faire tout cela dès le départ.



Collectivement, les techniques optimisent tous les éléments de Google Core Web Vitals en:



  • minimiser les problèmes de contenu majeurs ( Largest Contentful Paint (LCP) ) grâce à la réduction de la taille, la mise en cache et le chargement différé;
  • préservation du décalage de mise en page cumulatif nul (décalage de mise en page cumulatif (CLS) );
  • réduire le délai de la première entrée ( First Input Delay (FID) ) en réduisant la consommation du processeur (pour le thread principal d'exécution).


Pour voir toutes les techniques en action, jetez un œil au code source pour charger cette image:



https://www.industrialempathy.com/img/remote/ZiClJf.jpg
<img loading="lazy" decoding="async" style="background-size: cover; background-image: none;" src="/img/remote/ZiClJf.avif" alt="Sample image illustrating the techniques outlined in this post." width="4032" height="2268">

      
      







Techniques d'optimisation



Mise en page réactive



Cette technique simple permet à l'image d'occuper l'espace horizontal disponible tout en conservant le rapport hauteur / largeur. En 2020, les navigateurs ont appris à réserver la bonne quantité d'espace vertical pour une image avant son chargement si l'élément img



contient des attributs width



et height



. Cela évite le décalage cumulatif de la mise en page.



<style>
 img {
   max-width: 100%;
   height: auto;
 }
</style>
<!-- Providing width and height is more important than ever. -->
<img height="853" width="1280" … />

      
      





Rendu paresseux



La deuxième technique est plus compliquée. Le nouvel attribut CSS content-visibility: auto



indique au navigateur de ne pas penser à placer l'image tant qu'elle n'est pas prête. Cette approche présente plusieurs avantages, dont le principal est que tant que le navigateur ne reçoit pas une image d'espace réservé floue ou l'image elle-même, il ne la décodera pas, ce qui économise les ressources du processeur.



Plus besoin de contenir-intrinsèque-taille



Une version antérieure de l'article expliquait comment contain-intrinsic-size



éviter l'effet CLS lors de l'utilisation content-visibility: auto



. Mais dans Chromium 88, ce n'est plus nécessaire dans le cas d'images pour lesquelles width



et height



. À compter du 27 janvier 2021, content-visibility: auto



pas encore implémentés dans d'autres moteurs de navigateur
, ils suivront probablement l'exemple de Chromium. Alors oui, c'est beaucoup plus facile maintenant!



<style>
 /* This probably only makes sense for images within the main scrollable area of your page. */
 main img {
   /* Only render when in viewport */
   content-visibility: auto;
 }
</style>

      
      





AVIF



AVIF est le format graphique le plus récent pris en charge par les navigateurs. Il est désormais pris en charge dans Chromium et par indicateur dans Firefox. Safari ne fonctionne pas encore avec lui, mais comme Apple fait partie du groupe qui a développé le format, ce navigateur devrait également prendre en charge AVIF à l'avenir.



Ce format est remarquable en ce qu'il est largement supérieur au JPEG. Et cela se compare favorablement au format WebP, dont les images ne sont pas toujours plus petites que JPEG et qui peuvent augmenter la consommation de ressources en raison du manque de prise en charge du chargement progressif.



Pour implémenter une extension progressive pour AVIF, vous pouvez utiliser picture



.



L'élément est en fait img



imbriqué dans picture



... Cela peut être déroutant, car on l'appelle img



parfois une solution de secours pour les navigateurs qui ne prennent pas en charge picture



, mais en fait, cet élément ne fait qu'aider à la sélection src



, et il n'a pas sa propre disposition. L'élément img



sera dessiné et vous lui appliquerez le style.



Jusqu'à récemment, il était assez difficile d'implémenter des images AVIF côté serveur, mais les versions récentes de bibliothèques comme sharp rendaient cette tâche beaucoup plus facile.



<picture>
 <source
   sizes="(max-width: 608px) 100vw, 608px"
   srcset="
     /img/Z1s3TKV-1920w.avif 1920w,
     /img/Z1s3TKV-1280w.avif 1280w,
     /img/Z1s3TKV-640w.avif   640w,
     /img/Z1s3TKV-320w.avif   320w
   "
   type="image/avif"
 />
 <!-- snip lots of other stuff -->
 <img />
</picture>

      
      





Chargement du nombre correct de pixels



Le code ci-dessus a des attributs srcset



et sizes



. Ils utilisent un sélecteur w



pour indiquer au navigateur quelle URL prendre en fonction du nombre physique de pixels nécessaire pour rendre l'image sur un appareil particulier. Ce montant dépend de la largeur de l'image, qui est calculée en fonction de l'attribut sizes



(qui est une expression de la requête multimédia).



Cela garantit que le navigateur chargera toujours la plus petite image possible, offrant la meilleure qualité sur un appareil particulier. Alternativement, il peut sélectionner la plus petite image si l'utilisateur a activé le mode de sauvegarde des données.



Solution de secours



Pour les navigateurs qui ne prennent en charge que les anciens formats d'image, vous pouvez srcset



fournir plus d'éléments bruts à l'aide de:



<source
 sizes="(max-width: 608px) 100vw, 608px"
 srcset="
   /img/Z1s3TKV-1920w.webp 1920w,
   /img/Z1s3TKV-1280w.webp 1280w,
   /img/Z1s3TKV-640w.webp   640w,
   /img/Z1s3TKV-320w.webp   320w
 "
 type="image/webp"
/>
<source
 sizes="(max-width: 608px) 100vw, 608px"
 srcset="
   /img/Z1s3TKV-1920w.jpg 1920w,
   /img/Z1s3TKV-1280w.jpg 1280w,
   /img/Z1s3TKV-640w.jpg   640w,
   /img/Z1s3TKV-320w.jpg   320w
 "
 type="image/jpeg"
/>

      
      





Mise en cache et URL immuables



Incorporez dans l'URL de l'image un hachage du nombre d'octets que l'image occupe. Dans l'exemple ci-dessus, je l'ai fait avec Z1s3TKV



. Lorsque vous modifiez l'image, l'URL change également, ce qui signifie que vous pouvez appliquer une mise en cache infinie des images. Les en-têtes de mise en cache doivent ressembler à cache-control: public,max-age=31536000,immutable



.



immutable



C'est une signification sémantiquement correcte cache-control



, mais elle a peu de support de navigateur aujourd'hui (je vous regarde, Chrome). max-age=31536000



- méthode de mise en cache de secours tout au long de l'année. public



est nécessaire à votre CDN pour mettre en cache l'image et la diffuser à partir du bord du réseau. Mais cette approche ne peut être utilisée que si elle ne viole pas vos politiques de confidentialité.



Chargement paresseux



En ajoutant loading=«lazy»



à l'élément, img



nous disons au navigateur de commencer à récupérer l'image uniquement lorsqu'elle est prête à être rendue.



<img loading="lazy" … />

      
      





Décryptage asynchrone



En ajoutant decoding=«async»



à l'élément, img



nous permettons au navigateur de décrypter l'image en dehors du flux principal afin que cette procédure n'interfère pas avec l'utilisateur. Il ne devrait y avoir aucun défaut notable dans cette solution, sauf qu'elle n'est pas toujours applicable par défaut dans les anciens navigateurs.



<img decoding="async" … />

      
      





Talon flou



Un stub flou est une image en ligne qui donne à l'utilisateur une idée d'une image à part entière qui sera chargée plus tard, sans transfert de données sur le réseau.



https://www.industrialempathy.com/img/blurry.svg





Quelques notes de mise en œuvre:



  • Le stub est incrusté comme des background-image



    images. Cette technique vous permet de supprimer le deuxième élément HTML en masquant littéralement le stub lorsque l'image principale est chargée, aucun JavaScript n'est nécessaire.
  • L'URI des données d'image principale est enveloppé dans l'URI des données d'image SVG. Ceci est fait parce que le flou se fait au niveau SVG et sans utiliser de filtre CSS. Autrement dit, le flou est effectué une fois pour chaque image rastérisée par SVG, pas pour chaque mise en page. Cela économise les ressources du processeur.


<img
 style="
     …
     background-size: cover;
     background-image:
       url('data:image/svg+xml;charset=utf-8,%3Csvg xmlns=\'http%3A//www.w3.org/2000/svg\'

xmlns%3Axlink=\'http%3A//www.w3.org/1999/xlink\' viewBox=\'0 0 1280 853\'%3E%3Cfilter id=\'b\' color-interpolation-filters=\'sRGB\'%3E%3CfeGaussianBlur stdDeviation=\'.5\'%3E%3C/feGaussianBlur%3E%3CfeComponentTransfer%3E%3CfeFuncA type=\'discrete\' tableValues=\'1 1\'%3E%3C/feFuncA%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Cimage filter=\'url(%23b)\' x=\'0\' y=\'0\' height=\'100%25\' width=\'100%25\'
       xlink%3Ahref=\'data%3Aimage/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAGCAIAAACepSOSAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAs0lEQVQI1wGoAFf/AImSoJSer5yjs52ktp2luJuluKOpuJefsoCNowB+kKaOm66grL+krsCnsMGrt8m1u8mzt8OVoLIAhJqzjZ2tnLLLnLHJp7fNmpyjqbPCqLrRjqO7AIeUn5ultaWtt56msaSnroZyY4mBgLq7wY6TmwCRfk2Pf1uzm2WulV+xmV6rmGyQfFm3nWSBcEIAfm46jX1FkH5Djn5AmodGo49MopBLlIRBfG8yj/dfjF5frTUAAAAASUVORK5CYII=\'%3E%3C/image%3E%3C/svg%3E');
   "
 …
/>

      
      





(Facultatif) Optimisation JavaScript



Les navigateurs peuvent être obligés de pixelliser le stub flou même si l'image est déjà chargée. Le problème peut être résolu en supprimant la pixellisation au démarrage. De plus, si votre image comporte des zones transparentes, cette optimisation devient obligatoire, sinon un stub apparaîtra à travers l'image.



<sript>
 document.body.addEventListener(
   "load",
   (e) => {
     if (e.target.tagName != "IMG") {
       return;
     }
     // Remove the blurry placeholder.
     e.target.style.backgroundImage = "none";
   },
   /* capture */ true
 );
</sript>

      
      





aditionellement



Un outil utile qui implémente toutes les optimisations décrites: onzeventy-high-performance-blog



All Articles