Bonnes pratiques concernant le chargement différé

Si les images et les vidéos à chargement différé présentent des performances positives et mesurables, d'avantages, ce n'est pas une tâche à prendre à la légère. Si vous vous trompez, il pourrait y avoir peut avoir des conséquences inattendues. Par conséquent, il est important de conserver à l’esprit des préoccupations.

Faites attention à la ligne de flottaison

Il peut être tentant de charger de manière différée chaque ressource multimédia de la page avec JavaScript, mais vous devez résister à cette tentation. Tout ce qui se trouve au-dessus du fold ne doit pas être chargé en différé. Ces ressources doivent être considérées comme essentielles et doit donc être chargé normalement.

Le chargement différé retarde le chargement des ressources jusqu'à ce que le DOM soit interactif lorsque le chargement des scripts est terminé et que leur exécution commence. Pour les images situées sous plier, c'est parfait, mais les ressources critiques au-dessus du pli doivent être chargées avec l'élément <img> standard afin qu'ils s'affichent dès que possible.

Bien sûr, où se trouve la ligne de flottaison n'est pas aussi évidente de nos jours, lorsque les sites Web sont sur un si grand nombre d’écrans de tailles différentes. Ce qui se trouve au-dessus de la ligne de flottaison sur un ordinateur portable peuvent se trouver en dessous sur les appareils mobiles. Il n’y a pas de conseils irrésistibles pour pour y répondre de manière optimale en toutes circonstances. Vous devrez mener une l'inventaire des éléments critiques de votre page, puis chargez ces images dans des mode.

En outre, vous ne souhaitez peut-être pas être aussi strict sur la ligne de pli que de déclenchement du chargement différé. Il est peut-être plus idéal pour vos objectifs créez une zone tampon à une certaine distance en dessous du pli pour que les images commencent bien avant que l'utilisateur ne les fasse défiler dans la fenêtre d'affichage. Par exemple, L'API Intersection Observer vous permet de spécifier une propriété rootMargin dans un options lorsque vous créez une instance IntersectionObserver. Ce attribue efficacement un tampon aux éléments, ce qui déclenche un comportement de chargement différé avant l'élément se trouve dans la fenêtre d'affichage:

let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
  // lazy-loading image code goes here
}, {
  rootMargin: "0px 0px 256px 0px"
});

Si la valeur de rootMargin ressemble à celles que vous spécifiez pour un CSS margin, c'est parce que c'est le cas. Dans ce cas, marge inférieure de l'élément observé (la fenêtre d'affichage par défaut du navigateur, pouvant être remplacé par un élément spécifique à l'aide de la propriété root) est élargi de 256 de pixels. Cela signifie que la fonction de rappel s'exécute lorsqu'un élément image est à 256 pixels de la fenêtre d'affichage pour que le chargement de l'image commence. avant que l'utilisateur ne les voie.

Pour obtenir le même résultat dans les navigateurs non compatibles avec Intersection Observe, utilisez le code de gestion des événements de défilement et ajustez votre Vérification getBoundingClientRect pour inclure un tampon.

Décalage de mise en page et espaces réservés

Le chargement différé peut entraîner un décalage de la mise en page si aucun espace réservé n'est utilisé. Ces modifications peuvent désorienter les utilisateurs et déclencher des mises en page DOM onéreuses. qui consomment des ressources système et contribuent aux à-coups. Au minimum, envisagez d'utiliser un espace réservé de couleur unie occupant les mêmes dimensions que la ou de techniques telles que LQIP ou SQIP qui évoquent le contenu d'un contenu multimédia avant de se charger.

Pour les balises <img>, src doit initialement pointer vers un espace réservé jusqu'à ce que cela est mis à jour avec l'URL finale de l'image. Utilisez l'attribut poster dans un L'élément <video> doit pointer vers une image d'espace réservé. De plus, utilisez width et Attributs height sur les balises <img> et <video> Cela garantit que le passage des espaces réservés aux images finales ne modifie pas la taille de rendu de l'élément pendant le chargement des médias.

Retards de décodage des images

Le chargement de grandes images en JavaScript et leur dépôt dans le DOM peuvent thread principal, ce qui entraîne le blocage de l'interface utilisateur pendant une courte période pendant le décodage. Décoder des images de manière asynchrone à l'aide de decode méthode avant de les insérer dans le DOM peut réduire ce type d'à-coups, mais Attention: cette fonctionnalité n'est pas encore disponible partout, ce qui complexifie la logique de chargement différé. Si vous souhaitez l'utiliser, vous devez le vérifier. Sous les émissions comment utiliser Image.decode() avec une solution de remplacement:

var newImage = new Image();
newImage.src = "my-awesome-image.jpg";

if ("decode" in newImage) {
  // Fancy decoding logic
  newImage.decode().then(function() {
    imageContainer.appendChild(newImage);
  });
} else {
  // Regular image load
  imageContainer.appendChild(newImage);
}

Consultez ce lien CodePen pour découvrir comme dans cet exemple en action. Si la plupart de vos images sont assez petites, Cela ne vous fera peut-être pas grand-chose, mais cela peut certainement aider à réduire les à-coups lorsque avec le chargement différé et les insérer dans le DOM.

Lorsque les éléments ne se chargent pas

Il arrive que des ressources multimédias ne se chargent pas pour une raison ou une autre, et des erreurs se produisent. Quand ? Cela dépend, mais voici un scénario hypothétique vous avez défini une règle de mise en cache HTML pour une courte période (par exemple, minutes), et l'utilisateur visite le site ou un utilisateur a laissé un onglet non actualisé ouvert pendant une longue période (plusieurs heures, par exemple) et revient lire votre contenu. Un redéploiement a lieu à un moment donné de ce processus. Au cours de ce déploiement, le nom de la ressource d'image change en raison de la gestion des versions basée sur le hachage, ou est supprimé dans son ensemble. Lorsque l'utilisateur charge l'image en différé, la ressource est indisponible, et échoue donc.

Bien qu'il s'agisse d'occurrences relativement rares, il peut être judicieux de disposer d'une sauvegarde en cas d'échec du chargement différé. Pour les images, une telle solution peut ressembler à ceci : ceci:

var newImage = new Image();
newImage.src = "my-awesome-image.jpg";

newImage.onerror = function(){
  // Decide what to do on error
};
newImage.onload = function(){
  // Load the image
};

En cas d'erreur, la procédure à suivre dépend de votre application. Pour Par exemple, vous pouvez remplacer la zone d'espace réservé de l'image par un bouton qui permet l'utilisateur d'essayer de charger à nouveau l'image ou simplement d'afficher un message d'erreur dans la zone réservée aux images.

D'autres scénarios peuvent également se présenter. Quoi que vous fassiez, ce n'est jamais une mauvaise idée de signaler à l'utilisateur qu'une erreur s'est produite, et éventuellement lui proposer une action à prendre en cas de problème.

Disponibilité de JavaScript

Ne partez pas du principe que JavaScript est toujours disponible. Si vous choisissez les images à chargement différé, pensez à proposer le balisage <noscript> qui affichera les images dans cas, JavaScript n'est pas disponible. L'exemple de remplacement le plus simple implique Utilisation d'éléments <noscript> pour diffuser des images si JavaScript est désactivé:

Je suis une image !

Si JavaScript est désactivé, les utilisateurs voient à la fois l'image de remplacement et le bouton image contenue avec les éléments <noscript>. Pour vous déplacer, placez Une classe de no-js sur la balise <html>, comme suit:

<html class="no-js">

Placez ensuite une ligne de script intégré dans <head> avant toute feuille de style. sont demandées via des balises <link> qui suppriment la classe no-js de <html>. si JavaScript est activé:

<script>document.documentElement.classList.remove("no-js");</script>

Enfin, utilisez du code CSS pour masquer des éléments avec une classe "lazy" lorsque JavaScript n'est pas disponible:

.no-js .lazy {
  display: none;
}

Cela n'empêche pas le chargement des images d'espace réservé, mais cela permet souhaitable. Les personnes pour lesquelles JavaScript est désactivé obtiennent autre chose qu'un espace réservé ce qui est préférable à des espaces réservés et à l'absence de contenu d'image pertinent tout.