Le lazy loading (chargement différé) des images consiste à ne pas télécharger une image tant qu’elle n’est pas sur le point d’entrer à l’écran. En HTML, il s’active en ajoutant loading="lazy" à la balise <img>, sans JavaScript ni bibliothèque, et tous les navigateurs actuels le prennent en charge. La règle la plus importante est de ne pas l’appliquer à l’image principale de la page (celle qui compte pour le LCP), qui doit se charger au plus tôt.
Dans cet article, vous verrez comment fonctionne l’attribut, comment le combiner avec fetchpriority et decoding, quelles erreurs le transforment en pénalité au lieu d’une amélioration et comment vérifier qu’il fonctionne.
Ce que fait exactement loading=“lazy”
Quand le navigateur rencontre une image avec loading="lazy", au lieu de la télécharger immédiatement, il attend que l’utilisateur s’en approche en faisant défiler la page. La distance à partir de laquelle le téléchargement commence est décidée par le navigateur (dans Chrome, elle dépend du type de connexion et vaut généralement plusieurs centaines de pixels), de sorte que l’image est normalement prête quand elle apparaît.
<img src="/img/graphique.webp" alt="Graphique des visites mensuelles" width="800" height="500" loading="lazy" decoding="async" />
L’attribut accepte deux valeurs :
lazy: diffère le chargement jusqu’à ce que l’image soit proche de la zone visible.eager: charge immédiatement (comportement par défaut si vous n’indiquez rien).
Selon Can I use, la prise en charge est universelle dans les navigateurs modernes : Chrome depuis la version 77, Firefox depuis la 75, Safari depuis la 15.4 et Edge depuis la 79. Un navigateur ancien qui ne le comprend pas ignore simplement l’attribut et charge l’image comme d’habitude ; aucun risque qu’elle ne s’affiche pas.
Pourquoi c’est important : moins d’octets et un meilleur LCP
Une page avec vingt images qui n’en affiche que trois à l’écran télécharge, sans lazy loading, les vingt. Avec loading="lazy" sur celles qui sont hors écran, elle en télécharge trois et le reste au fur et à mesure. Résultat : moins de transfert, moins de concurrence pour la bande passante et, le plus important pour les Core Web Vitals, les ressources critiques (l’image principale, les polices, le CSS) arrivent plus tôt.
La règle d’or : ne pas différer l’image du LCP
Le LCP (Largest Contentful Paint) mesure le moment où le plus grand élément visible est peint. Dans la plupart des articles et pages produit, cet élément est l’image à la une. Si vous lui mettez loading="lazy", le navigateur la traite comme non prioritaire et la charge plus tard qu’il ne pourrait : le LCP se dégrade. La documentation de web.dev sur l’optimisation du LCP est explicite sur ce point.
Pour l’image principale, c’est l’inverse qu’il faut faire :
<img src="/img/couverture.webp" alt="Couverture de l’article" width="1200" height="630" loading="eager" fetchpriority="high" decoding="async" />
loading="eager"(ou simplement omettre l’attribut) pour qu’elle se télécharge immédiatement.fetchpriority="high"pour indiquer au navigateur que cette image est plus importante que les autres ressources de même catégorie.
Règle pratique : l’image déjà visible au chargement de la page, sans défilement, n’est pas différée. Les autres, si.
fetchpriority et decoding : les deux autres attributs
fetchpriority
fetchpriority ajuste la priorité relative d’une requête. Il accepte high, low et auto. Utilisez-le avec high sur l’image du LCP et, si vous le souhaitez, avec low sur des images décoratives d’un carrousel non visibles au départ. Le mettre sur toutes les images n’a pas de sens : si tout est prioritaire, rien ne l’est.
decoding
decoding="async" permet au navigateur de décoder l’image hors du thread principal, de sorte que le reste de la page n’attend pas. Il est sûr de l’utiliser sur pratiquement toutes les images de contenu. L’alternative sync n’a de sens que dans des cas très précis où l’image doit apparaître exactement dans la même frame que le texte qui l’entoure.
Toujours avec width et height
Lazy loading et dimensions vont ensemble. Si le navigateur ne sait pas quelle taille occupera une image qu’il n’a pas encore téléchargée, il réserve zéro pixel et, quand elle arrive, pousse le contenu vers le bas. C’est un saut de mise en page (CLS), un autre des Core Web Vitals. Déclarez toujours width et height avec les dimensions réelles de l’image ; le CSS peut la redimensionner (max-width: 100%; height: auto;) sans perdre les proportions.
Images de fond CSS et iframes
L’attribut loading n’existe que sur <img> et <iframe>. Les images de fond définies en CSS (background-image) ne peuvent pas être différées avec lui ; si vous en avez besoin, il faudra passer par JavaScript avec IntersectionObserver ou reconsidérer si cette image ne devrait pas être un <img> dans le HTML (ce qui est, en plus, meilleur pour l’accessibilité et le SEO).
Pour les iframes (vidéos intégrées, cartes), cela fonctionne de la même façon :
<iframe src="https://www.youtube-nocookie.com/embed/ID" title="Titre de la vidéo" width="560" height="315" loading="lazy"></iframe>
Erreurs fréquentes
- Mettre
loading="lazy"à toutes les images automatiquement. Beaucoup de plugins WordPress le font. Vérifiez que l’image à la une est exclue. - Sans width ni height. Cela produit du CLS et, dans certains navigateurs, dégrade le chargement différé, qui ne peut pas calculer la distance à la zone visible.
- Images masquées avec
display: none. Elles se téléchargent quand même dès que le navigateur les juge « proches ». Si elles ne doivent pas s’afficher, ne les mettez pas dans le HTML. - Compter sur le lazy loading pour régler des images énormes. Différer le chargement ne réduit pas le poids. Redimensionnez et convertissez en WebP ou AVIF d’abord ; différez ensuite.
Comment vérifier que ça fonctionne
Ouvrez les outils de développement du navigateur, onglet Réseau, filtrez sur les images et rechargez la page sans faire défiler. Seules les images visibles doivent apparaître. En descendant, vous verrez les autres se demander au fur et à mesure. Dans Lighthouse, l’audit « Defer offscreen images » disparaît quand tout est correct, et « Largest Contentful Paint image was lazily loaded » vous avertit si vous avez différé l’image principale par erreur.
Conclusion
loading="lazy" est la façon la plus simple et la plus sûre de réduire le poids initial d’une page avec beaucoup d’images : un attribut, pas de JavaScript et une prise en charge universelle. Pour que ce soit une vraie amélioration, accompagnez-le de width et height, utilisez decoding="async", et laissez l’image principale en dehors avec loading="eager" et fetchpriority="high". Différer ce qui ne se voit pas et prioriser ce qui se voit, c’est en substance toute la stratégie.