Chargement différé des images et des éléments <iframe>

Les images et les éléments <iframe> consomment souvent plus de bande passante que les autres types de ressources. Dans le cas des éléments <iframe>, le chargement et l'affichage des pages qu'ils contiennent peuvent nécessiter un certain temps de traitement supplémentaire.

Dans le cas d'images à chargement différé, le fait de différer le chargement des images qui se trouvent en dehors de la fenêtre d'affichage initiale peut être utile pour réduire les conflits de bande passante pour des ressources plus critiques dans la fenêtre d'affichage initiale. Cela peut améliorer le LCP (Largest Contentful Paint) d'une page dans certains cas où les connexions réseau sont mauvaises, et que la bande passante réaffectée peut aider les candidats LCP à se charger et à peindre plus rapidement.

En ce qui concerne les éléments <iframe>, il est possible d'améliorer l'Interaction to Next Paint (INP) d'une page au démarrage grâce à un chargement différé. En effet, <iframe> est un document HTML entièrement distinct doté de ses propres sous-ressources. Bien que les éléments <iframe> puissent être exécutés dans un processus distinct, il n'est pas rare qu'ils partagent un processus avec d'autres threads, ce qui peut créer des conditions où les pages deviennent moins réactives à l'entrée utilisateur.

Ainsi, le report du chargement des images hors écran et des éléments <iframe> est une technique utile qui nécessite un effort relativement faible pour obtenir un retour raisonnable en termes de performances. Ce module explique comment effectuer le chargement différé de ces deux types d'éléments afin d'améliorer et d'accélérer l'expérience utilisateur pendant la période de démarrage critique de la page.

Images de chargement différé avec l'attribut loading

Vous pouvez ajouter l'attribut loading aux éléments <img> pour indiquer aux navigateurs comment ils doivent être chargés:

  • "eager" indique au navigateur que l'image doit être chargée immédiatement, même si elle se trouve en dehors de la fenêtre d'affichage initiale. Il s'agit également de la valeur par défaut de l'attribut loading.
  • "lazy" diffère le chargement d'une image jusqu'à ce qu'elle se trouve à une distance définie par rapport à la fenêtre d'affichage visible. Cette distance varie selon le navigateur, mais est souvent définie pour être suffisamment grande pour que l'image se charge lorsque l'utilisateur fait défiler la page jusqu'à elle.

Notez également que si vous utilisez l'élément <picture>, l'attribut loading doit toujours être appliqué à son élément <img> enfant, pas à l'élément <picture> lui-même. En effet, l'élément <picture> est un conteneur qui contient des éléments <source> supplémentaires pointant vers différentes images candidates, et la suggestion choisie par le navigateur est appliquée directement à son élément <img> enfant.

Évitez le chargement différé des images qui se trouvent dans la fenêtre d'affichage initiale.

Vous ne devez ajouter l'attribut loading="lazy" qu'aux éléments <img> qui sont positionnés en dehors de la fenêtre d'affichage initiale. Cependant, il peut être complexe de connaître la position précise d'un élément par rapport dans la fenêtre d'affichage avant que la page ne soit affichée. Les tailles de fenêtres d'affichage, les formats et les appareils doivent être pris en compte.

Par exemple, une fenêtre d'affichage pour ordinateur peut être très différente d'une fenêtre d'affichage sur un téléphone mobile, car elle affiche plus d'espace vertical qui peut s'adapter à des images qui ne s'afficheraient pas dans la fenêtre d'affichage initiale d'un appareil physique plus petit. Les tablettes utilisées en orientation portrait affichent également un espace vertical considérable, peut-être même plus que certains ordinateurs de bureau.

Toutefois, dans certains cas, il est assez clair d'éviter d'appliquer loading="lazy". Par exemple, vous devez absolument omettre l'attribut loading="lazy" des éléments <img> dans les cas d'images héros ou dans d'autres cas d'utilisation d'images où les éléments <img> sont susceptibles d'apparaître au-dessus de la ligne de flottaison ou près du haut de la mise en page sur n'importe quel appareil. Ceci est encore plus important pour les images susceptibles d'être des candidats au LCP.

Les images à chargement différé doivent attendre que le navigateur finisse la mise en page pour savoir si la position finale de l'image se trouve dans la fenêtre d'affichage. Cela signifie que si un élément <img> dans la fenêtre d'affichage visible comporte un attribut loading="lazy", il n'est demandé qu'après le téléchargement, l'analyse et l'application de tout le code CSS sur la page (plutôt que d'être récupéré dès qu'il est découvert par l'outil de préchargement dans le balisage brut).

Étant donné que l'attribut loading de l'élément <img> est compatible avec tous les principaux navigateurs, il n'est pas nécessaire d'utiliser JavaScript pour charger les images de manière différée. En effet, l'ajout de code JavaScript supplémentaire à une page pour fournir les fonctionnalités déjà fournies par le navigateur affecte d'autres aspects des performances de la page, tels que l'INP.

Démonstration du chargement différé des images

Éléments <iframe> de chargement différé

Le chargement différé des éléments <iframe> jusqu'à ce qu'ils soient visibles dans la fenêtre d'affichage peut économiser des données importantes et améliorer le chargement des ressources critiques nécessaires au chargement de la page de premier niveau. De plus, comme les éléments <iframe> sont essentiellement des documents HTML entiers chargés dans un document de premier niveau, ils peuvent inclure un nombre important de sous-ressources, en particulier JavaScript, ce qui peut considérablement affecter l'INP d'une page si les tâches dans ces cadres nécessitent un temps de traitement important.

Les intégrations tierces sont un cas d'utilisation courant pour les éléments <iframe>. Par exemple, les lecteurs vidéo intégrés ou les posts sur les réseaux sociaux utilisent généralement des éléments <iframe> et nécessitent souvent un nombre important de sous-ressources, ce qui peut également entraîner des conflits de bande passante pour les ressources de la page de premier niveau. Par exemple, le chargement différé de l'intégration d'une vidéo YouTube permet d'économiser plus de 500 Kio lors du chargement initial de la page, tandis que le chargement différé du plug-in du bouton "J'aime" de Facebook permet d'économiser plus de 200 Kio, principalement en JavaScript.

Quoi qu'il en soit, chaque fois qu'une <iframe> est présente en dessous de la ligne de flottaison sur une page, vous devez envisager le chargement différé s'il n'est pas essentiel de la charger à l'avance, car cela peut améliorer considérablement l'expérience utilisateur.

Attribut loading pour les éléments <iframe>

L'attribut loading sur les éléments <iframe> est également compatible avec tous les principaux navigateurs. Les valeurs de l'attribut loading et leurs comportements sont les mêmes que pour les éléments <img> qui utilisent l'attribut loading:

  • "eager" est la valeur par défaut. Elle demande au navigateur de charger immédiatement le code HTML de l'élément <iframe> et ses sous-ressources.
  • "lazy" diffère le chargement du code HTML de l'élément <iframe> et de ses sous-ressources jusqu'à ce qu'il se trouve à une distance prédéfinie par rapport à la fenêtre d'affichage.

Démonstration des iFrames à chargement différé

Façades

Au lieu de charger une intégration immédiatement pendant le chargement de la page, vous pouvez la charger à la demande en réponse à une interaction utilisateur. Pour ce faire, vous pouvez afficher une image ou un autre élément HTML approprié jusqu'à ce que l'utilisateur interagisse avec. Une fois que l'utilisateur a interagi avec l'élément, vous pouvez le remplacer par l'intégration tierce. Cette technique est connue sous le nom de façade.

Un cas d'utilisation courant des façades est l'intégration de vidéos à partir de services tiers. L'intégration peut nécessiter le chargement de nombreuses sous-ressources supplémentaires et potentiellement coûteuses, telles que JavaScript, en plus du contenu vidéo lui-même. Dans ce cas, sauf en cas d'utilité légitime de la lecture automatique d'une vidéo, l'intégration d'une vidéo nécessite que l'utilisateur interagisse avec elle en cliquant sur le bouton de lecture avant la lecture.

C'est une excellente occasion d'afficher une image statique visuellement semblable à l'intégration vidéo et d'économiser beaucoup de bande passante au cours du processus. Lorsque l'utilisateur clique sur l'image, elle est remplacée par l'intégration <iframe> réelle, qui déclenche le téléchargement du code HTML de l'élément <iframe> tiers et de ses sous-ressources.

En plus d'améliorer le chargement initial de la page, un autre avantage clé est que si l'utilisateur ne lit jamais la vidéo, les ressources nécessaires pour la diffuser ne sont jamais téléchargées. Il s'agit d'un bon modèle, car il garantit que l'utilisateur ne télécharge que ce qu'il souhaite réellement, sans faire d'hypothèses potentiellement erronées sur ses besoins.

Les widgets de chat constituent un autre excellent cas d'utilisation pour la technique de façade. La plupart des widgets de chat téléchargent une quantité importante de code JavaScript, qui peut avoir un impact négatif sur le chargement des pages et la réactivité aux entrées utilisateur. Comme pour le chargement initial, le coût est facturé au moment du chargement. Toutefois, dans le cas d'un widget de chat, tous les utilisateurs n'ont pas l'intention d'interagir avec celui-ci.

En revanche, avec une façade, il est possible de remplacer le bouton tiers "Démarrer le chat" par un faux bouton. Une fois que l'utilisateur interagit de manière significative avec lui, par exemple en plaçant un pointeur dessus pendant une période raisonnable ou en cliquant dessus, le widget de chat fonctionnel réel est placé en place lorsque l'utilisateur en a besoin.

Bien qu'il soit certainement possible de créer vos propres façades, il existe des options Open Source pour les applications tierces plus populaires, telles que lite-youtube-embed pour les vidéos YouTube, lite-vimeo-embed pour les vidéos Vimeo et React Live Chat Loader pour les widgets de chat.

Bibliothèques à chargement différé JavaScript

Si vous devez charger des éléments <video> ou poster, des images chargées par la propriété CSS background-image ou d'autres éléments non compatibles, vous pouvez le faire avec une solution de chargement différé basée sur JavaScript, telle que lazysizes ou yall.js, car le chargement différé de ces types de ressources n'est pas une fonctionnalité au niveau du navigateur.<video>

En particulier, la lecture automatique et la lecture en boucle des éléments <video> sans piste audio sont une alternative beaucoup plus efficace que les GIF animés, qui peuvent souvent être plusieurs fois plus volumineux qu'une ressource vidéo de qualité visuelle équivalente. Malgré cela, ces vidéos peuvent toujours être significatives en termes de bande passante. Par conséquent, leur chargement différé constitue une optimisation supplémentaire qui peut grandement réduire le gaspillage de bande passante.

La plupart de ces bibliothèques fonctionnent à l'aide de l'API Intersection Observer, et de l'API Mutation Observer si le code HTML d'une page est modifié après le chargement initial. Cela permet de reconnaître quand un élément entre dans la fenêtre d'affichage de l'utilisateur. Si l'image est visible ou en approche de la fenêtre d'affichage, la bibliothèque JavaScript remplace l'attribut non standard (souvent data-src ou un attribut similaire) par l'attribut approprié, tel que src.

Imaginons que l'une de vos vidéos remplace un GIF animé, mais que vous souhaitiez la charger de manière différée avec une solution JavaScript. Cela est possible avec yall.js avec le modèle de balisage suivant:

<!-- The autoplay, loop, muted, and playsinline attributes are to
     ensure the video can autoplay without user intervention. -->
<video class="lazy" autoplay loop muted playsinline width="320" height="480">
  <source data-src="video.webm" type="video/webm">
  <source data-src="video.mp4" type="video/mp4">
</video>

Par défaut, yall.js observe tous les éléments HTML éligibles avec une classe "lazy". Une fois que yall.js est chargé et exécuté sur la page, la vidéo ne se charge pas tant que l'utilisateur ne la fait pas défiler dans la fenêtre d'affichage. À ce stade, les attributs data-src des éléments <source> enfants de l'élément <video> sont remplacés par les attributs src, ce qui envoie une requête pour télécharger la vidéo et la lire automatiquement.

Tester vos connaissances

Quelle est la valeur par défaut de l'attribut loading pour les éléments <img> et <iframe> ?

"eager"
Bonne réponse !
"lazy"
Réessayez.

Dans quels cas est-il judicieux d'utiliser des solutions de chargement différé basées sur JavaScript ?

Pour toutes les ressources pouvant faire l'objet d'un chargement différé.
Réessayez.
Pour les ressources dans lesquelles l'attribut loading n'est pas accepté, par exemple pour les vidéos en lecture automatique destinées à remplacer les images animées ou pour le chargement différé de l'image poster d'un élément <video>.
Bonne réponse !

Dans quel cas la façade est-elle une technique utile ?

Pour toute intégration tierce qui consomme beaucoup de données, quels que soient les besoins de l'utilisateur.
Réessayez.
Pour toute intégration tierce où les ressources requises pour le chargement ne sont pas seulement conséquentes, il est très probable que tous les utilisateurs n'interagissent pas avec elles.
Bonne réponse !

À suivre: Préchargement et prérendu

Maintenant que vous maîtrisez les images à chargement différé et les éléments <iframe>, vous pouvez vous assurer que les pages se chargent plus rapidement tout en respectant les besoins de vos utilisateurs. Toutefois, dans certains cas, un chargement spéculatif des ressources peut être souhaitable. Dans le module suivant, vous découvrirez le préchargement et le prérendu, et comment ces techniques, lorsqu'elles sont utilisées avec soin, peuvent considérablement accélérer la navigation vers les pages suivantes en les chargeant à l'avance.