Images à chargement différé

Les images peuvent apparaître sur une page Web, car elles sont intégrées dans le code HTML en tant qu'éléments <img> ou comme images d'arrière-plan CSS. Dans cet article, vous allez découvrir comment effectuer le chargement différé des deux types d'images.

Images intégrées

Les candidats au chargement différé les plus courants sont les images utilisées dans les éléments <img>. Pour les images intégrées, trois options de chargement différé sont disponibles : que vous pouvez combiner pour optimiser la compatibilité avec les différents navigateurs:

Utiliser le chargement différé au niveau du navigateur

Chrome et Firefox sont tous deux compatibles avec le chargement différé avec l'attribut loading. Cet attribut peut être ajouté aux éléments <img>, ainsi qu'aux éléments <iframe>. La valeur lazy indique au navigateur de charger immédiatement l'image si elle se trouve dans la fenêtre d'affichage. et d'extraire d'autres images lorsque l'utilisateur fait défiler la page à proximité.

Voir le champ loading des MDN compatibilité des navigateurs pour en savoir plus sur les navigateurs compatibles. Si le navigateur n'accepte pas le chargement différé, l'attribut sera ignoré. et les images se chargent immédiatement, comme d'habitude.

Pour la plupart des sites Web, l'ajout de cet attribut aux images intégrées permet d'améliorer les performances. et faire en sorte que les utilisateurs chargent des images qu'ils n'ont pas le temps de faire défiler. Si vous disposez d'un grand nombre d'images et souhaitez vous assurer que les utilisateurs de navigateurs non compatibles avec le chargement différé vous devrez l'associer à l'une des méthodes expliquées ci-après.

Pour en savoir plus, consultez Chargement différé au niveau du navigateur pour le Web.

Utiliser l'observateur d'intersection

Pour émuler le chargement différé des éléments <img>, nous utilisons JavaScript afin de vérifier s'ils se trouvent dans fenêtre d'affichage. Si c'est le cas, leurs attributs src (et parfois srcset) sont contenant les URL des images souhaitées.

Si vous avez déjà écrit du code à chargement différé, vous avez peut-être accompli votre tâche à l'aide de gestionnaires d'événements tels que scroll ou resize. Bien que cette approche soit les plus compatibles avec tous les navigateurs, les navigateurs récents offrent un accès efficace de vérifier la visibilité des éléments via la méthode API Intersection Observer :

Intersection Observer est plus facile à utiliser et à lire que le code en s'appuyant sur divers des gestionnaires d'événements, car il vous suffit d'enregistrer un observateur pour surveiller au lieu d'écrire un code fastidieux pour détecter la visibilité des éléments. Tout il reste à décider quoi faire lorsqu'un élément est visible. Supposons que vous utilisiez ce schéma de balisage de base pour vos éléments <img> chargés en différé:

<img class="lazy" src="placeholder-image.jpg" data-src="image-to-lazy-load-1x.jpg" data-srcset="image-to-lazy-load-2x.jpg 2x, image-to-lazy-load-1x.jpg 1x" alt="I'm an image!">

Vous devez vous concentrer sur trois éléments pertinents de ce balisage:

  1. L'attribut class, avec lequel vous sélectionnerez l'élément dans JavaScript.
  2. L'attribut src, qui fait référence à une image d'espace réservé qui apparaît lorsque la page se charge en premier.
  3. Les attributs data-src et data-srcset, qui sont des attributs d'espace réservé contenant l'URL de l'image à charger une fois l'élément placé dans la fenêtre d'affichage.

Voyons maintenant comment utiliser l'observateur d'intersection en JavaScript pour effectuer un chargement différé. images utilisant ce format de balisage:

document.addEventListener("DOMContentLoaded", function() {
  var lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));

  if ("IntersectionObserver" in window) {
    let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
      entries.forEach(function(entry) {
        if (entry.isIntersecting) {
          let lazyImage = entry.target;
          lazyImage.src = lazyImage.dataset.src;
          lazyImage.srcset = lazyImage.dataset.srcset;
          lazyImage.classList.remove("lazy");
          lazyImageObserver.unobserve(lazyImage);
        }
      });
    });

    lazyImages.forEach(function(lazyImage) {
      lazyImageObserver.observe(lazyImage);
    });
  } else {
    // Possibly fall back to event handlers here
  }
});

Lors de l'événement DOMContentLoaded du document, ce script interroge le DOM pour toutes Éléments <img> avec une classe de lazy. Si l'outil Intersection Observer est disponible, Créez un observateur qui exécute un rappel lorsque des éléments img.lazy entrent dans le fenêtre d'affichage.

Intersection Observer est disponible dans tous les navigateurs récents. Par conséquent, l'utiliser comme polyfill pour loading="lazy" garantira que le chargement différé sera disponible pour la plupart des visiteurs.

Images dans CSS

Bien que les balises <img> soient le moyen le plus courant d'utiliser des images sur des pages Web, les images peut également être appelé via le CSS background-image (et d'autres propriétés). Le chargement différé au niveau du navigateur ne s'applique pas aux images de fond CSS, Vous devez donc envisager d'autres méthodes si vous disposez d'images de fond à charger en différé.

Contrairement aux éléments <img>, qui se chargent indépendamment de visibilité, le comportement de chargement d'image en CSS est obtenu spéculations. Lorsque le document et l'objet CSS modèles de ML et rendu arbre le navigateur examine comment le CSS est appliqué à un document avant demandant des ressources externes. Si le navigateur a défini une règle CSS impliquant une ressource externe ne s'applique pas au document, le navigateur ne le demande pas.

Ce comportement spéculatif peut être utilisé pour différer le chargement d'images dans CSS : Utiliser JavaScript pour déterminer si un élément se trouve dans la fenêtre d'affichage puis en appliquant à cet élément une classe qui applique un style en appelant une comme une image d'arrière-plan. L'image est alors téléchargée au moment où l'utilisateur en a besoin. et non lors du chargement initial. Prenons l'exemple d'un élément contenant une grande image d'arrière-plan principale:

<div class="lazy-background">
  <h1>Here's a hero heading to get your attention!</h1>
  <p>Here's hero copy to convince you to buy a thing!</p>
  <a href="/buy-a-thing">Buy a thing!</a>
</div>

L'élément div.lazy-background contient normalement l'arrière-plan du héros. appelée par un CSS. Dans cet exemple de chargement différé, vous pouvez isoler la propriété background-image de l'élément div.lazy-background via une visible ; ajoutée à l'élément lorsqu'il se trouve dans la fenêtre d'affichage:

.lazy-background {
  background-image: url("hero-placeholder.jpg"); /* Placeholder image */
}

.lazy-background.visible {
  background-image: url("hero.jpg"); /* The final image */
}

À partir de là, utilisez JavaScript pour vérifier si l'élément se trouve dans la fenêtre d'affichage (avec Intersection Observer!) et ajoutez la classe visible au div.lazy-background à ce moment-là, qui charge l'image:

document.addEventListener("DOMContentLoaded", function() {
  var lazyBackgrounds = [].slice.call(document.querySelectorAll(".lazy-background"));

  if ("IntersectionObserver" in window) {
    let lazyBackgroundObserver = new IntersectionObserver(function(entries, observer) {
      entries.forEach(function(entry) {
        if (entry.isIntersecting) {
          entry.target.classList.add("visible");
          lazyBackgroundObserver.unobserve(entry.target);
        }
      });
    });

    lazyBackgrounds.forEach(function(lazyBackground) {
      lazyBackgroundObserver.observe(lazyBackground);
    });
  }
});

Effets sur le Largest Contentful Paint (LCP)

Le chargement différé est une excellente optimisation qui réduit à la fois la consommation globale des données et les conflits sur le réseau au démarrage en reportant le chargement des images au moment où elles sont réellement nécessaires. Cela peut améliorer le temps de démarrage et réduire le traitement sur le thread principal en réduisant le temps nécessaire au décodage des images.

Toutefois, le chargement différé est une technique qui peut avoir un impact négatif sur le LCP Largest Contentful Paint de votre site Web si vous en acceptez trop. Il convient d'éviter les images à chargement différé qui s'affichent dans la fenêtre d'affichage au démarrage.

Lorsque vous utilisez des chargeurs différés basés sur JavaScript, évitez le chargement différé des images dans la fenêtre d'affichage, car ces solutions utilisent souvent un attribut data-src ou data-srcset comme espace réservé pour les attributs src et srcset. Le problème est que le chargement de ces images sera retardé, car le scanner de préchargement du navigateur ne les trouve pas au démarrage.

Même l'utilisation du chargement différé au niveau du navigateur pour le chargement différé d'une image dans la fenêtre d'affichage peut avoir un effet inverse. Lorsque loading="lazy" est appliqué à une image dans la fenêtre d'affichage, cette image est retardée jusqu'à ce que le navigateur sache qu'elle se trouve dans la fenêtre d'affichage, ce qui peut affecter le LCP d'une page.

Ne jamais d'images à chargement différé qui sont visibles dans la fenêtre d'affichage au démarrage. Ce modèle aura un impact négatif sur le LCP de votre site, et donc sur l'expérience utilisateur. Si vous avez besoin d'une image au démarrage, chargez-la le plus rapidement possible au démarrage en évitant le chargement différé.

Bibliothèques à chargement différé

Dans la mesure du possible, utilisez le chargement différé au niveau du navigateur. Toutefois, si vous vous trouvez dans une situation où cela n'est pas possible (par exemple, un grand nombre d'utilisateurs utilisent encore des navigateurs plus anciens), vous pouvez utiliser les bibliothèques suivantes pour charger des images en différé:

  • lazysizes est une plate-forme paresseuse complète qui charge les images et les iFrames de manière différée. Le modèle utilisé est assez similaire aux exemples de code présentés ici, dans la mesure où il est automatiquement lié lazyload sur les éléments <img>, et nécessite que vous spécifiiez les URL d'image dans Attributs data-src et/ou data-srcset, dont le contenu est échangé en attributs src et/ou srcset, respectivement. Il utilise Intersection "Observer" (que vous pouvez émuler), et peut être étendu avec plusieurs des plug-ins comme le chargement différé des vidéos. En savoir plus sur l'utilisation des tailles différées
  • vanilla-lazyload est un pour les images à chargement différé, les images de fond, les vidéos, les cadres iFrame et scripts. Il exploite Intersection Observer, prend en charge les images responsives et active le chargement différé au niveau du navigateur.
  • lozad.js est un autre fichier qui n'utilise que l'outil Intersection Observer. Il est donc très performant, mais il devra être polyrempli avant de pouvoir l'utiliser sur des navigateurs plus anciens.
  • Si vous avez besoin d'une bibliothèque de chargement différé spécifique à React, envisagez react-lazyload. Bien qu'il n'utilise pas Intersection Observer, mais il fournit une méthode familière d'affichage différé de chargement d'images pour ceux qui ont l'habitude de développer des applications avec React.