Chargement différé des images au niveau du navigateur pour le Web

Le chargement différé intégré est enfin disponible !

Les images au chargement différé sont désormais compatibles avec les images sur le Web. Cette vidéo présente une démonstration de cette fonctionnalité:

Vous pouvez utiliser l'attribut loading pour charger des images en différé sans avoir à écrire de code de chargement différé personnalisé ni à utiliser une bibliothèque JavaScript distincte. Entrons dans les détails.

Compatibilité du navigateur

Navigateurs pris en charge

  • 77
  • 79
  • 75
  • 15,4

Les navigateurs qui ne sont pas compatibles avec l'attribut loading l'ignorent simplement sans effets secondaires.

Pourquoi le chargement différé au niveau du navigateur ?

Selon l'archive HTTP, les images sont le type d'élément le plus demandé pour la plupart des sites Web et consomment généralement plus de bande passante que toute autre ressource. Au 90e centile, les sites envoient plus de 5 Mo d'images sur ordinateur et sur mobile. Cela fait beaucoup de photos de chat.

Auparavant, il existait deux façons de différer le chargement des images hors écran:

Ces deux options peuvent permettre aux développeurs d'inclure une fonctionnalité de chargement différé. De plus, de nombreux développeurs ont créé des bibliothèques tierces pour fournir des abstractions encore plus faciles à utiliser. Cependant, le chargement différé étant directement pris en charge par le navigateur, il n'est pas nécessaire d'avoir une bibliothèque externe. Le chargement différé au niveau du navigateur garantit également que le chargement différé des images fonctionne toujours, même si JavaScript est désactivé sur le client.

Attribut loading

Chrome charge les images avec des priorités différentes en fonction de leur emplacement par rapport à la fenêtre d'affichage de l'appareil. Les images situées sous la fenêtre d'affichage sont chargées avec une priorité inférieure, mais elles sont tout de même extraites lors du chargement de la page.

Vous pouvez utiliser l'attribut loading pour différer complètement le chargement des images hors écran accessibles par défilement:

<img src="image.png" loading="lazy" alt="…" width="200" height="200">

Voici les valeurs acceptées pour l'attribut loading:

  • lazy: reporte le chargement de la ressource jusqu'à ce qu'elle atteigne une distance calculée par rapport à la fenêtre d'affichage.
  • eager: comportement de chargement par défaut du navigateur, qui revient à ne pas inclure l'attribut et qui signifie que l'image est chargée quel que soit son emplacement sur la page. Bien qu'il s'agisse du paramètre par défaut, il peut être utile de le définir explicitement si votre outil ajoute automatiquement loading="lazy" en l'absence de valeur explicite, ou si l'outil lint fait une réclamation si elle n'est pas explicitement définie.

Relation entre l'attribut loading et la priorité de récupération

La valeur eager est simplement une instruction permettant de charger l'image comme d'habitude, sans retarder davantage le chargement si elle se trouve hors de l'écran. Cela ne signifie pas que l'image se charge plus rapidement qu'une autre image sans l'attribut loading="eager".

Les navigateurs hiérarchisent les ressources en fonction de diverses méthodes heuristiques, et l'attribut loading indique simplement quand la ressource image est mise en file d'attente, et non comment elle est prioritaire dans cette file d'attente. eager implique simplement les navigateurs de mise en file d'attente hâtives habituels utilisés par défaut.

Si vous souhaitez augmenter la priorité de récupération d'une image importante (par exemple, l'image LCP), utilisez Fetch Priority (Priorité de récupération) avec fetchpriority="high".

Notez qu'une image avec loading="lazy" et fetchpriority="high" est toujours retardée tant qu'elle n'est pas affichée en dehors de l'écran, puis extraite avec une priorité élevée lorsqu'elle se trouve presque dans la fenêtre d'affichage. Dans ce cas, elle sera probablement récupérée avec une priorité élevée. Cette combinaison ne devrait donc pas être vraiment nécessaire ni utilisée.

Seuils de distance par rapport à la fenêtre d'affichage

Toutes les images situées dans la partie au-dessus de la ligne de flottaison (c'est-à-dire immédiatement visibles sans faire défiler la page) se chargent normalement. Ceux qui se trouvent bien en dessous de la fenêtre d'affichage de l'appareil ne sont récupérés que lorsque l'utilisateur fait défiler la page à proximité.

L'implémentation du chargement différé dans Chromium vise à s'assurer que les images hors écran sont chargées suffisamment tôt pour que leur chargement se termine une fois que l'utilisateur fait défiler la page vers elles. En récupérant les images à proximité bien avant qu'elles ne soient visibles dans la fenêtre d'affichage, nous maximiseons les chances qu'elles soient déjà chargées lorsqu'elles deviennent visibles.

Par rapport aux bibliothèques JavaScript à chargement différé, les seuils d'extraction d'images qui défilent jusqu'à l'affichage peuvent être considérés comme prudents.

Le seuil de distance n'est pas fixe et varie en fonction de plusieurs facteurs:

Vous trouverez les valeurs par défaut des différents types de connexion efficaces dans la source Chromium. Ces chiffres, et même l'approche consistant à effectuer des extractions uniquement lorsqu'une certaine distance par rapport à la fenêtre d'affichage est atteinte, peuvent changer à l'avenir, car l'équipe Chrome améliore les méthodes heuristiques pour déterminer quand commencer le chargement.

Amélioration des seuils d'économies de données et de distance par rapport à la fenêtre d'affichage

Depuis juillet 2020, Chrome a apporté d'importantes améliorations pour aligner les seuils de distance de chargement différé des images par rapport à la fenêtre d'affichage afin de mieux répondre aux attentes des développeurs.

Pour les connexions rapides (4G), nous avons réduit les seuils de distance entre la fenêtre d'affichage de Chrome de 3000px à 1250px. Pour les connexions plus lentes (3G ou moins), nous avons fait passer le seuil de 4000px à 2500px. Ce changement a deux objectifs:

  • <img loading=lazy> se comporte plus près de l'expérience offerte par les bibliothèques de chargement différé JavaScript.
  • Les nouveaux seuils de distance par rapport à la fenêtre d'affichage nous permettent toujours de garantir que les images ont probablement été chargées au moment où l'utilisateur fait défiler la page jusqu'à elles.

Vous trouverez ci-dessous une comparaison entre les anciens et les nouveaux seuils de distance par rapport à la fenêtre d'affichage pour l'une de nos démonstrations sur une connexion rapide (4G) :

Anciens seuils et nouveaux seuils:

Nouveaux seuils améliorés pour le chargement différé des images, réduisant les seuils de distance entre la fenêtre d&#39;affichage pour les connexions rapides de 3 000 à 1 250 px

et les nouveaux seuils par rapport à LazySizes (une bibliothèque populaire de chargement différé JS):

Nouveaux seuils de distance par rapport à la fenêtre d&#39;affichage pour le chargement de 90 Ko d&#39;images dans Chrome, contre 70 Ko pour le chargement de LazySize dans les mêmes conditions de réseau

Nous nous engageons à collaborer avec la communauté des normes Web pour trouver une meilleure approche des seuils de distance par rapport à la fenêtre d'affichage dans les différents navigateurs.

Les images doivent inclure des attributs de dimensions

Lorsque le navigateur charge une image, il n'en connaît pas immédiatement les dimensions, sauf si elles sont explicitement spécifiées. Afin de permettre au navigateur de réserver suffisamment d'espace pour les images sur une page, il est recommandé que toutes les balises <img> incluent à la fois les attributs width et height. Si les dimensions ne sont pas spécifiées, des changements de mise en page peuvent se produire sur les pages dont le chargement prend un certain temps.

<img src="image.png" loading="lazy" alt="…" width="200" height="200">

Vous pouvez également spécifier leurs valeurs directement dans un style intégré:

<img src="image.png" loading="lazy" alt="…" style="height:200px; width:200px;">

La bonne pratique qui consiste à définir des dimensions s'applique aux balises <img>, que leur chargement soit différé ou non. Avec le chargement différé, cela peut devenir plus pertinent. Dans les navigateurs récents, la définition de width et height sur les images permet également à ces derniers de déduire leur taille intrinsèque.

Dans la plupart des cas, les images se chargent toujours de manière différée si les dimensions ne sont pas incluses, mais il existe quelques cas particuliers que vous devez connaître. Si width et height ne sont pas spécifiés, les dimensions de l'image sont de 0 × 0 pixel. Si vous disposez d'une galerie d'images de ce type, le navigateur peut en conclure qu'elles tiennent toutes dans la fenêtre d'affichage au début, car chacune n'occupe pratiquement aucun espace et aucune image n'est déplacée hors de l'écran. Dans ce cas, le navigateur détermine qu'ils sont tous visibles par l'utilisateur et décide de tous les charger.

En outre, spécifier les dimensions de l'image réduit le risque de décalage de la mise en page. Si vous ne pouvez pas inclure de dimensions pour vos images, leur chargement différé peut être un compromis entre l'enregistrement des ressources réseau et le risque de décalage de la mise en page.

Bien que le chargement différé dans Chromium soit mis en œuvre de sorte que les images soient susceptibles d'être chargées une fois qu'elles sont visibles, il est encore possible qu'elles ne soient pas encore chargées. Dans ce cas, les attributs width et height manquants sur ces images augmentent leur impact sur le Cumulative Layout Shift.

Les images définies à l'aide de l'élément <picture> peuvent également être chargées en différé:

<picture>
  <source media="(min-width: 800px)" srcset="large.jpg 1x, larger.jpg 2x">
  <img src="photo.jpg" loading="lazy">
</picture>

Bien qu'un navigateur décide quelle image charger à partir de n'importe quel élément <source>, l'attribut loading ne doit être inclus que dans l'élément <img> de remplacement.

Éviter les images à chargement différé situées dans la première fenêtre d'affichage visible

Évitez de définir loading=lazy pour les images qui se trouvent dans la première fenêtre d'affichage visible. Ceci est particulièrement pertinent pour les images LCP. Pour en savoir plus, consultez l'article Effets d'un chargement différé trop important sur les performances.

Dans la mesure du possible, nous vous recommandons d'ajouter uniquement loading=lazy aux images qui sont placées en dessous de la ligne de flottaison. Les images chargées hâtivement peuvent être récupérées immédiatement, tandis que les images chargées de manière différée, le navigateur doit actuellement attendre de savoir où l'image est positionnée sur la page, ce qui s'appuie sur le IntersectionObserver pour être disponible.

En règle générale, les images de la fenêtre d'affichage doivent être chargées rapidement en utilisant les paramètres par défaut du navigateur. Il n'est pas nécessaire de spécifier loading=eager pour que cela soit le cas pour les images dans la fenêtre d'affichage.

<!-- visible in the viewport -->
<img src="product-1.jpg" alt="..." width="200" height="200">
<img src="product-2.jpg" alt="..." width="200" height="200">
<img src="product-3.jpg" alt="..." width="200" height="200">

<!-- offscreen images -->
<img src="product-4.jpg" loading="lazy" alt="..." width="200" height="200">
<img src="product-5.jpg" loading="lazy" alt="..." width="200" height="200">
<img src="product-6.jpg" loading="lazy" alt="..." width="200" height="200">

Dégradation progressive

Les navigateurs qui ne sont pas compatibles avec l'attribut loading ignoreront sa présence. Bien entendu, ces navigateurs ne bénéficieront pas des avantages du chargement différé, mais inclure cet attribut n'aura aucun impact négatif sur eux.

Questions fréquentes

Prévoyez-vous d'effectuer automatiquement le chargement différé des images dans Chrome ?

Auparavant, Chromium chargeait automatiquement de manière différée toutes les images pouvant être différées si le mode simplifié était activé sur Chrome pour Android et que l'attribut loading n'était pas fourni ou était défini sur loading="auto". Cependant, le mode simplifié est obsolète (tout comme le loading="auto" non standard), et il n'est actuellement pas prévu de proposer le chargement différé automatique des images dans Chrome.

Puis-je modifier la proximité nécessaire d'une image pour déclencher un chargement ?

Ces valeurs sont codées en dur et ne peuvent pas être modifiées via l'API. Toutefois, ils peuvent changer à l'avenir, car les navigateurs expérimentent différentes distances de seuil et variables.

Les images d'arrière-plan CSS peuvent-elles exploiter l'attribut loading ?

Non, elle ne peut actuellement être utilisée qu'avec des balises <img>.

Y a-t-il un inconvénient à utiliser des images au chargement différé dans la fenêtre d'affichage de l'appareil ?

Il est plus sûr d'éviter d'ajouter loading=lazy sur les images au-dessus de la ligne de flottaison, car Chrome ne précharge pas les images loading=lazy dans le préchargement d'écran et retarde également la récupération de ces images jusqu'à la fin de la mise en page. Pour en savoir plus, consultez Éviter le chargement différé des images qui se trouvent dans la première fenêtre d'affichage visible.

L'utilisation de loading="lazy" peut empêcher leur chargement lorsqu'ils ne sont pas visibles, mais dans la distance calculée. Par exemple, Chrome, Safari et Firefox ne chargent pas les images en utilisant le style display: none;, que ce soit sur l'élément image ou sur un élément parent. Toutefois, d'autres techniques permettant de masquer des images, telles que le style opacity:0, entraînent le chargement des images. Testez toujours votre implémentation minutieusement pour vous assurer qu'elle fonctionne comme prévu.

Que se passe-t-il si j'utilise déjà une bibliothèque tierce ou un script pour charger des images en différé ?

Les navigateurs récents étant désormais entièrement compatibles avec le chargement différé natif, vous pouvez reconsidérer si vous avez toujours besoin d'une bibliothèque ou d'un script tiers pour charger les images en différé.

L'une des raisons de continuer à utiliser une bibliothèque tierce avec loading="lazy" est de fournir un polyfill pour les navigateurs qui ne prennent pas en charge l'attribut ou de mieux contrôler le moment où le chargement différé est déclenché.

Comment gérer les navigateurs qui ne sont pas compatibles avec le chargement différé ?

Créez un polyfill ou utilisez une bibliothèque tierce pour charger les images en différé sur votre site. La propriété loading permet de déterminer si la fonctionnalité est compatible avec le navigateur:

if ('loading' in HTMLImageElement.prototype) {
  // supported in browser
} else {
  // fetch polyfill/third-party library
}

Par exemple, lazysizes est une bibliothèque JavaScript populaire à chargement différé. Vous ne pouvez détecter la prise en charge de l'attribut loading pour charger des tailles différées en tant que bibliothèque de remplacement que lorsque loading n'est pas compatible. Cela fonctionne comme suit:

  • Remplacez <img src> par <img data-src> pour éviter une charge hâtive dans les navigateurs non compatibles. Si l'attribut loading est accepté, remplacez data-src par src.
  • Si loading n'est pas compatible, chargez une création de remplacement (tailles différées) et lancez-la. Conformément à la documentation sur les tailles différées, vous utilisez la classe lazyload pour indiquer aux tailles différées quelles images doivent être chargées en différé.
<!-- Let's load this in-viewport image normally -->
<img src="hero.jpg" alt="…">

<!-- Let's lazy-load the rest of these images -->
<img data-src="unicorn.jpg" alt="…" loading="lazy" class="lazyload">
<img data-src="cats.jpg" alt="…" loading="lazy" class="lazyload">
<img data-src="dogs.jpg" alt="…" loading="lazy" class="lazyload">

<script>
  if ('loading' in HTMLImageElement.prototype) {
    const images = document.querySelectorAll('img[loading="lazy"]');
    images.forEach(img => {
      img.src = img.dataset.src;
    });
  } else {
    // Dynamically import the LazySizes library
    const script = document.createElement('script');
    script.src =
      'https://cdnjs.cloudflare.com/ajax/libs/lazysizes/5.1.2/lazysizes.min.js';
    document.body.appendChild(script);
  }
</script>

Voici une démonstration de ce modèle. Essayez-la dans une ancienne version de navigateur pour voir la création de remplacement en action.

Le chargement différé pour les iFrames est-il également compatible avec les navigateurs ?

Navigateurs pris en charge

  • 77
  • 79
  • 121
  • 16.4

<iframe loading=lazy> a également été normalisé et est déjà implémenté dans Chromium et Safari. Cela vous permet de procéder au chargement différé des iFrame à l'aide de l'attribut loading. Pour en savoir plus, consultez cet article dédié sur le chargement différé des cadres iFrame.

Comment le chargement différé au niveau du navigateur affecte-t-il les publicités sur une page Web ?

Toutes les annonces présentées à l'utilisateur sous la forme d'une image ou d'un iFrame avec chargement différé, comme n'importe quelle autre image ou iFrame.

Comment les images sont-elles traitées lorsqu'une page Web est imprimée ?

Si la page est imprimée, toutes les images et tous les iFrames sont immédiatement chargés. Pour en savoir plus, consultez le problème 875403.

Lighthouse reconnaît-il le chargement différé au niveau du navigateur ?

Lighthouse 6.0 et les versions ultérieures prennent en compte les approches de chargement différé des images hors écran qui peuvent utiliser différents seuils, ce qui leur permet de réussir l'audit Différer les images hors écran.

Conclusion

L'intégration de la prise en charge des images au chargement différé peut vous permettre d'améliorer considérablement les performances de vos pages Web.

Avez-vous remarqué un comportement inhabituel lorsque cette fonctionnalité est activée dans Chrome ? Signalez un bug.