Chargement paresseux hybride : une migration progressive vers le chargement paresseux natif

Publié: 2022-03-10
Résumé rapide ↬ Le chargement paresseux natif arrive sur le Web. Puisqu'il ne dépend pas de JavaScript, il révolutionnera la façon dont nous chargeons le contenu paresseux aujourd'hui, ce qui facilitera le chargement paresseux des images et des iframes pour les développeurs. Mais ce n'est pas une fonctionnalité que nous pouvons polyfiller, et il faudra un certain temps avant qu'elle ne devienne utilisable sur tous les navigateurs. Dans cet article, vous apprendrez comment cela fonctionne et comment vous pouvez progressivement remplacer votre chargement paresseux basé sur JavaScript par son alternative native, grâce au chargement paresseux hybride.

Au cours des dernières semaines, vous avez peut-être entendu ou lu des articles sur le chargement paresseux natif, qui arrivera sur Chromium 75 dans les mois à venir.

"Ouais, bonne nouvelle, mais nous devrons attendre que tous les navigateurs le prennent en charge."

Si c'est la première chose qui vous a traversé l'esprit, continuez à lire. Je vais essayer de vous convaincre du contraire.

Commençons par une comparaison entre le chargement paresseux natif et le bon vieux JavaScript.

Chargement paresseux natif versus JavaScript

Le chargement différé est un moyen d'améliorer les performances d'un site Web ou d'une application Web en maximisant la vitesse de rendu des images et des iframes au-dessus de la ligne de flottaison (et parfois des vidéos) en différant le chargement du contenu en dessous de la ligne de flottaison.

Chargement paresseux piloté par JavaScript

Afin de charger paresseusement des images ou des iframes, il est très courant de les marquer en remplaçant l'attribut src approprié par un attribut de données similaire, data-src , puis de s'appuyer sur une solution JavaScript pour détecter le moment où les images/iframes obtiennent près de la partie visible du site Web (généralement parce que l'utilisateur a fait défiler vers le bas) et de copier les attributs de données dans les bons, déclenchant alors le chargement différé de leur contenu.

 <img data-src="turtle.jpg" alt="Lazy turtle" class="lazy">
Plus après saut! Continuez à lire ci-dessous ↓

Chargement paresseux natif

Selon la spécification native de chargement paresseux (toujours en cours de développement), si vous souhaitez charger paresseusement des images ou des iframes à l'aide de la fonction native de chargement paresseux, il vous suffit d'ajouter l'attribut loading=lazy sur la balise associée.

 <img src="turtle.jpg" alt="Lazy turtle" loading="lazy">

Addy Osmani a beaucoup écrit sur ce sujet dans son article "Native Image Lazy-Loading For The Web!" dans lequel il a déclaré que l'équipe de Google Chrome développait déjà la fonctionnalité et avait l'intention de l'expédier dans Chrome 75.

D'autres navigateurs basés sur Chromium comme Opera et Microsoft Edge bénéficieront également de ce développement en obtenant la même fonctionnalité dans leur première mise à jour basée sur Chromium 75.

Premiers pas avec le chargement paresseux natif

Dans le cas où les images de votre site Web sont téléchargées en une seule fois à la page d'accueil sans chargement paresseux, vous pouvez activer (le cas échéant) le chargement paresseux natif sur votre site Web aussi facilement qu'en ajoutant un attribut HTML. L'attribut loading indique aux navigateurs quelles images sont importantes à charger immédiatement et lesquelles peuvent être téléchargées paresseusement lorsque les utilisateurs défilent vers le bas. Le même attribut peut être appliqué aux iframes.

Afin d'indiquer aux navigateurs qu'une image particulière est importante afin qu'ils puissent la charger dès que possible, vous devez ajouter l'attribut loading="eager" sur la balise img . La meilleure pratique consiste à le faire pour les images principales - généralement pour celles qui seront affichées au-dessus du pli.

 <img src="rabbit.jpg" alt="Fast rabbit" loading="eager">

Pour indiquer aux navigateurs qu'une image doit être téléchargée paresseusement, ajoutez simplement l'attribut loading="lazy" . Il s'agit d'une meilleure pratique uniquement si vous ne le faites que sur des images secondaires - généralement pour celles qui seront affichées sous le pli.

 <img src="turtle.jpg" alt="Lazy turtle" loading="lazy">

En ajoutant simplement l'attribut de loading à vos images et iframes, vous permettrez à votre site Web d'utiliser le chargement paresseux natif comme une amélioration progressive. Votre site Web en bénéficiera progressivement au fur et à mesure que le support arrivera à vos utilisateurs dans la plupart des navigateurs modernes.

C'est la meilleure approche à utiliser si votre site Web n'utilise aucun type de chargement paresseux aujourd'hui, mais si vous avez déjà implémenté une solution de chargement paresseux basée sur JavaScript, vous voudrez peut-être la conserver tout en passant progressivement au chargement paresseux natif.

La solution idéale serait de commencer immédiatement à utiliser le chargement paresseux natif et d'utiliser un polyfill pour le faire fonctionner sur tous les navigateurs. Malheureusement, le chargement paresseux natif n'est pas une fonctionnalité que nous pouvons remplir avec JavaScript.

Pas d'utilisation pour un polyfill

Lorsqu'une nouvelle technologie de navigateur est publiée sur un seul navigateur, la communauté open source publie généralement un polyfill JavaScript pour fournir la même technologie au reste des navigateurs. Par exemple, le polyfill IntersectionObserver utilise des éléments JavaScript et DOM pour coordonner Element.getBoundingClientRect() afin de reproduire le comportement de l'API native.

Mais le cas du chargement paresseux natif est différent car un polyfill JavaScript pour loading="lazy" devrait empêcher les navigateurs de charger du contenu dès qu'ils trouvent une URL dans le balisage d'une image ou d'une iframe. JavaScript n'a aucun contrôle sur cette étape initiale du rendu de la page, il n'est donc pas possible de remplir le chargement paresseux natif.

Chargement paresseux hybride

Si vous n'êtes pas satisfait du chargement paresseux natif uniquement en tant qu'amélioration progressive, ou si vous avez déjà implémenté le chargement paresseux basé sur JavaScript et que vous ne voulez pas perdre cette fonctionnalité dans les navigateurs moins modernes (mais que vous souhaitez toujours activer le chargement paresseux natif sur les navigateurs qui le prennent en charge), alors vous avez besoin d'une solution différente. Présentation : chargement paresseux hybride.

Le chargement paresseux hybride est une technique permettant d'utiliser le chargement paresseux natif sur les navigateurs qui le prennent en charge, sinon, comptez sur JavaScript pour gérer le chargement paresseux.

"

Pour effectuer un chargement paresseux hybride, vous devez baliser votre contenu paresseux en utilisant les attributs de data au lieu des vrais (comme dans le chargement paresseux piloté par JavaScript) et ajouter l'attribut loading="lazy" .

 <img data-src="turtle.jpg" loading="lazy" alt="Lazy turtle">

Ensuite, vous avez besoin de JavaScript. En premier lieu, vous devez détecter si le chargement différé natif est pris en charge ou non par le navigateur . Ensuite, effectuez l'une des opérations suivantes pour chaque élément avec l'attribut loading="lazy" :

  • Si le chargement différé natif est pris en charge, copiez la valeur de l'attribut data-src dans l'attribut src ;
  • S'il n'est pas pris en charge, initialisez un script ou un plug-in de chargement différé JavaScript pour le faire lorsque les éléments entrent dans la fenêtre d'affichage.

Il n'est pas très difficile d'écrire le code JavaScript nécessaire pour effectuer ces opérations par vous-même. Vous pouvez détecter si le chargement différé natif est pris en charge avec la condition :

 if ('loading' in HTMLImageElement.prototype)

Si c'est le cas, copiez simplement la valeur de l'attribut src depuis data-src . Si ce n'est pas le cas, initialisez un script de chargement différé de votre choix.

Voici un extrait de code qui fait cela.

 <!-- In-viewport images should be loaded normally, or eagerly --> <img src="important.jpg" loading="eager" alt="Important image"> <!-- Let's lazy-load the rest of these images --> <img data-src="lazy1.jpg" loading="lazy" alt="Lazy image 1"> <img data-src="lazy2.jpg" loading="lazy" alt="Lazy image 2"> <img data-src="lazy3.jpg" loading="lazy" alt="Lazy image 3"> <script> (function() { if ("loading" in HTMLImageElement.prototype) { var lazyEls = document.querySelectorAll("[loading=lazy]"); lazyEls.forEach(function(lazyEl) { lazyEl.setAttribute( "src", lazyEl.getAttribute("data-src") ); }); } else { // Dynamically include a lazy loading library of your choice // Here including vanilla-lazyload var script = document.createElement("script"); script.async = true; script.src = "https://cdn.jsdelivr.net/npm/[email protected]/dist/lazyload.min.js"; window.lazyLoadOptions = { elements_selector: "[loading=lazy]" //eventually more options here }; document.body.appendChild(script); } })(); </script>

Vous pouvez trouver et tester le code ci-dessus dans cette démo en direct.

Pourtant, c'est un script très basique, et les choses peuvent se compliquer lorsque vous utilisez des attributs ou des balises supplémentaires pour obtenir des images réactives (comme les srcset et sizes ou même les balises picture et source ).

Un peu d'aide de tiers

Au cours des quatre dernières années, j'ai maintenu un script de chargement paresseux open source nommé « vanilla-lazyload » et, quelques jours après qu'Addy Osmani ait écrit sur le chargement paresseux natif, la communauté a réagi en me demandant si mon script pouvait agir comme un polyfill.

Comme je l'ai expliqué précédemment, vous ne pouvez pas créer de polyfill pour la fonction de chargement paresseux natif, cependant, j'ai pensé à une solution qui permettrait aux développeurs de commencer plus facilement la transition vers le chargement paresseux natif, sans avoir besoin d'écrire le code JavaScript qui J'ai déjà mentionné.

À partir de la version 12 de vanilla-lazyload , vous pouvez simplement définir l'option use_native sur true pour activer le chargement différé hybride. Le script ne fait que 2,0 Ko et est déjà disponible sur GitHub, npm et jsDelivr.

  • Apprenez à connaître vanilla-lazyload sur GitHub

Démos

Vous pouvez commencer à jouer avec le chargement paresseux natif dès aujourd'hui en téléchargeant Chrome Canary ou Microsoft Edge Insider ( canal de développement ), puis en activant les drapeaux "Activer le chargement d'images paresseux" et "Activer le chargement d'images paresseux". Pour activer ces indicateurs, saisissez about:flags dans le champ URL de votre navigateur et recherchez « paresseux » dans la zone de recherche.

Démo de chargement paresseux natif

Pour analyser le fonctionnement du chargement paresseux natif dans les outils de développement, vous pouvez commencer à jouer avec la démo suivante. Dans celui-ci, pas une seule ligne de JavaScript n'est utilisée . Oui, c'est juste un chargement paresseux natif complet.

  • Testez la démo native de chargement paresseux

À quoi s'attendre : Toutes les images sont récupérées en même temps, mais avec des réponses HTTP différentes. Celles avec le code de réponse 200 sont les images chargées avec impatience, tandis que celles avec le code de réponse 206 ne sont que partiellement extraites afin d'obtenir les informations initiales sur les images. Ces images seront ensuite récupérées complètement avec un code de réponse 200 lorsque vous faites défiler vers le bas.

Démonstration de chargement paresseux hybride

Pour analyser le fonctionnement du chargement paresseux hybride, vous pouvez commencer à jouer avec la prochaine démo. Ici, [email protected] est utilisé et l'option use_native est définie sur true :

  • Testez la démo de chargement paresseux hybride

À quoi s'attendre : essayez la démo sur différents navigateurs pour voir comment elle se comporte. Sur les navigateurs prenant en charge le chargement différé natif, le comportement serait le même que dans la démo de chargement différé natif. Sur les navigateurs qui ne prennent pas en charge le chargement paresseux natif, les images seront téléchargées au fur et à mesure que vous faites défiler vers le bas.

Veuillez noter que vanilla-lazyload utilise l'API IntersectionObserver sous le capot, vous devrez donc la polyfill sur Internet Explorer et les versions moins récentes de Safari. Ce n'est pas grave si un polyfill n'est pas fourni, car dans ce cas, vanilla-lazyload téléchargerait simplement toutes les images en même temps.

Remarque : Pour en savoir plus, consultez le chapitre "To Polyfill Or Not To Polyfill" du fichier readme de vanilla-lazyload .

Essayez le chargement paresseux hybride sur votre site Web

Étant donné que le chargement paresseux natif arrive bientôt sur certains navigateurs, pourquoi ne pas lui donner une chance aujourd'hui en utilisant le chargement paresseux hybride ? Voici ce que vous devez faire :

Balisage HTML

Le balisage d'image le plus simple est constitué de deux attributs : src et alt .

Pour les images au-dessus de la ligne de flottaison, vous devez laisser l'attribut src et ajouter l'attribut loading="eager" .

 <img src="important.jpg" loading="eager" alt="Important image">

Pour les images en dessous de la ligne de flottaison, vous devez remplacer l'attribut src par l'attribut de data-src et ajouter l'attribut loading="lazy" .

 <img data-src="lazy.jpg" loading="lazy" alt="A lazy image">

Si vous souhaitez utiliser des images responsives, faites de même avec les srcset et sizes .

 <img alt="A lazy image" loading="lazy" data-src="lazy.jpg">

Si vous préférez utiliser la balise picture , modifiez srcset , sizes et src dans les balises source .

 <picture> <source media="(min-width: 1200px)"> <source media="(min-width: 800px)"> <img alt="A lazy image" loading="lazy" data-src="lazy.jpg"> </picture>

La balise d' picture peut également être utilisée pour charger de manière sélective le format WebP pour vos images.

Remarque : Si vous souhaitez en savoir plus sur les utilisations de vanilla-lazyload , veuillez lire la section HTML "Getting Started" de son fichier readme.

Code Javascript

Tout d'abord, vous devez inclure vanilla-lazyload sur votre site Web.

Vous pouvez le charger depuis un CDN comme jsDelivr :

 <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/lazyload.min.js"></script>

Ou vous pouvez l'installer en utilisant npm :

 npm install vanilla-lazyload@12

Il est également possible d'utiliser un script async avec initialisation automatique ; chargez-le en tant que module ES en utilisant type="module" ou chargez-le en tant qu'AMD en utilisant RequireJS. Trouvez d'autres façons d'inclure et d'utiliser vanilla-lazyload dans la section de script "Getting Started" du fichier readme.

Ensuite, dans le code JavaScript de votre site Web/application Web, incluez les éléments suivants :

 var pageLazyLoad = new LazyLoad({ elements_selector: "[loading=lazy]", use_native: true // ← enables hybrid lazy loading });

Remarque : Le script contient de nombreux autres paramètres que vous pouvez utiliser pour personnaliser le comportement de vanilla-lazyload , par exemple pour augmenter la distance de la zone de défilement à partir de laquelle commencer à charger les éléments ou pour charger les éléments uniquement s'ils sont restés dans la fenêtre pendant un certain temps. temps donné. Trouvez plus de paramètres dans la section API du fichier readme.

Tous ensemble, en utilisant un script async

Pour tout assembler et utiliser un script async pour optimiser les performances, veuillez vous référer au code HTML et JavaScript suivant :

 <!-- In-viewport images should be loaded normally, or eagerly --> <img src="important.jpg" loading="eager" alt="Important image"> <!-- Let's lazy-load the rest of these images --> <img data-src="lazy1.jpg" loading="lazy" alt="Lazy image 1"> <img data-src="lazy2.jpg" loading="lazy" alt="Lazy image 2"> <img data-src="lazy3.jpg" loading="lazy" alt="Lazy image 3"> <!-- Set the options for the global instance of vanilla-lazyload --> <script> window.lazyLoadOptions = { elements_selector: "[loading=lazy]", use_native: true // ← enables hybrid lazy loading }; </script> <!-- Include vanilla lazyload 12 through an async script --> <script async src="https://cdn.jsdelivr.net/npm/[email protected]/dist/lazyload.min.js"></script>

C'est ça! Avec ces étapes très simples et faciles, vous aurez activé le chargement paresseux hybride sur votre site Web !

Meilleures pratiques importantes

  • Appliquez le chargement paresseux uniquement aux images dont vous savez qu'elles seront probablement affichées sous le pli. Chargez avec impatience ceux au-dessus du pli pour maximiser les performances. Si vous appliquez simplement un chargement paresseux à toutes les images de votre page, vous ralentirez les performances de rendu.
  • Utilisez CSS pour réserver de l'espace pour les images avant qu'elles ne soient chargées. De cette façon, ils pousseront le reste du contenu ci-dessous. Si vous ne le faites pas, un plus grand nombre d'images seront placées au-dessus du pli avant qu'elles ne le devraient, déclenchant des téléchargements immédiats pour elles. Si vous avez besoin d'une astuce CSS pour le faire, vous pouvez en trouver une dans la section trucs et astuces du readme de vanilla-lazyload .

Avantages et inconvénients

CHARGEMENT NATIF PARESSANT
AVANTAGES
  • Aucun JavaScript requis ;
  • Pas de maux de tête d'installation, cela fonctionne tout simplement ;
  • Pas besoin de réserver de l'espace pour les images en utilisant des astuces CSS ;
LES INCONVÉNIENTS
  • Il ne fonctionne pas aujourd'hui sur tous les navigateurs ;
  • La charge utile initiale est plus élevée, en raison de la prélecture des 2 Ko initiaux pour chaque image.
CHARGEMENT LAZY PILOTÉ PAR JAVASCRIPT
AVANTAGES
  • Il fonctionne de manière cohérente sur tous les navigateurs, en ce moment ;
  • Vous pouvez faire des astuces d'interface utilisateur très personnalisées, comme l'effet de flou ou le chargement retardé.
LES INCONVÉNIENTS
  • Il s'appuie sur JavaScript pour charger votre contenu.
CHARGEMENT LAZY HYBRIDE
AVANTAGES
  • Il vous donne la possibilité d'activer et de tester le chargement paresseux natif lorsqu'il est pris en charge ;
  • Il permet le chargement différé sur tous les navigateurs ;
  • Vous pouvez supprimer de manière transparente la dépendance au script dès que la prise en charge native du chargement différé sera généralisée.
LES INCONVÉNIENTS
  • Il s'appuie toujours sur JavaScript pour charger votre contenu.

Emballer

Je suis très heureux que le chargement paresseux natif arrive sur les navigateurs, et j'ai hâte que tous les fournisseurs de navigateurs l'implémentent !

En attendant, vous pouvez choisir d'enrichir votre balisage HTML pour une amélioration progressive et d'obtenir un chargement paresseux natif uniquement lorsqu'il est pris en charge, ou vous pouvez opter pour un chargement paresseux hybride et obtenir un chargement paresseux natif et basé sur JavaScript jusqu'au jour où le chargement paresseux natif sera être pris en charge par la grande majorité des navigateurs.

Essaie! N'oubliez pas de mettre en vedette/regarder vanilla-lazyload sur GitHub, et faites-moi part de vos réflexions dans la section des commentaires.

Lectures complémentaires sur SmashingMag :

  • Maintenant, vous me voyez : comment différer, charger paresseux et agir avec IntersectionObserver
  • Chargement paresseux des modules JavaScript avec ConditionerJS
  • Liste de vérification des performances frontales 2019 (PDF, pages Apple, MS Word)
  • Comment l'amélioration des performances du site Web peut aider à sauver la planète