Nous avions déjà parlé du lazy loading natif en février et mai dernier. Depuis la version 76 de Chrome sortie cet été, le navigateur de Google supporte nativement l’attribut loading. Nous allons donc pouvoir analyser et comprendre la mise en place de ce nouvel attribut.
Petit rappel : pourquoi le lazy loading ?
Les images de 90% des sites web prennent plus de bande passante que toute autre ressource. Les iframes embarquées utilisent aussi beaucoup de données et peuvent nuire à la web performance des pages. Donc, différer le chargement des images et des iframes non visibles à l’écran au moment où l’utilisateur est susceptible de les voir :
- améliore les temps de chargement des pages,
- minimise la bande passante de l’utilisateur,
- et réduit la consommation de mémoire.
Actuellement, il faut obligatoirement utiliser JavaScript pour mettre en place un lazy loading :
- soit avec l’API Intersection Observe,
- soit avec un gestionnaire d’événements de défilement, de redimensionnement ou de changement d’orientation.
Il y a de nombreuses bibliothèques tierces sur le sujet qui permettent une implémentation plus ou moins aisée.
Avec un lazy loading directement pris en charge par le navigateur, il n’y a cependant plus besoin de bibliothèque JavaScript externe et cela garantit également que le chargement différé des images et des iframes fonctionne même si JavaScript est désactivé sur le client (et ça chez artwaï on aime beaucoup pour cause de “No Fucking JS Spirit” ).
L’attribut de chargement : loading
Par défaut, Chrome charge les images selon différentes priorités en fonction de leur emplacement par rapport à la fenêtre d’affichage du périphérique. Les images sous la ligne de flottaison sont chargées avec une priorité plus faible, mais elles sont quand même récupérées dès que possible.
Depuis Chrome 76, vous pouvez désormais utiliser l’attribut “loading” pour différer complètement le chargement des images et des iframes :
<img src="image.jpg" loading="lazy" alt="..."" width="200" height="200">
<iframe src="https://example.com" loading="lazy"></iframe>
L’attribut “loading” dispose de 3 valeurs :
- auto : comportement par défaut de lazy loading du navigateur, qui est le même que de ne pas inclure l’attribut.
- lazy : reporter le chargement de la ressource jusqu’à ce qu’elle entre dans la fenêtre d’affichage, dans le viewport.
- eager : chargez la ressource immédiatement, où qu’elle se trouve sur la page.
Seuil de distance de lancement du chargement
Toutes les images et les iframes qui sont au-dessus de la ligne de flottaison – c’est-à-dire immédiatement visibles sans défilement – sont chargées normalement. Les ressources qui se trouvent bien en dessous de la fenêtre d’affichage de l’appareil ne sont récupérées que lorsque l’utilisateur fait défiler l’écran près d’eux.
Le seuil de distance n’est pas fixe et varie en fonction de plusieurs facteurs :
- le type de ressource à récupérer (image ou iframe),
- et le type de connexion en cours.
Le seuil de distance est donc déterminé selon le type de connexion identifiée par le navigateur. Chromium définit 5 types de connection : slow2G, 2G, 3G, 4G, inconnu et hors ligne ; et attribut une distance de seuil pour chacun, respectivement : 8000, 6000, 4000, 3000, 5000 et 8000.
Cela signifie que le chargement de toutes les images dépend de votre connexion. Donc sans attribut spécifique (donc pas d’attribut loading ou avec loading = auto) et quelque soit leur nombre, toutes les images seront chargées avec une bonne connexion à moins d’être au delà du seuil de distance. Et plus votre connexion est mauvaise, plus le navigateur anticipera le chargement des images (le seuil de distance étant plus long – voir les valeurs ci-dessus).
Ces chiffres, et même l’approche consistant à aller chercher seulement lorsqu’une certaine distance du viewport est atteinte, peuvent changer. Car l’équipe de Chrome continue d’améliorer l’heuristique pour déterminer quand le chargement doit commencer.
Avec la valeur lazy
A l’inverse, avec l’attribut loading=”lazy”, l’image ne se charge qu’au moment où elle se trouve dans le viewport, c’est-à-dire dans la fenêtre d’affichage. Ce qui doit permettre de gagner en temps de chargement puisque les images non visibles ne seront ainsi pas chargées avant d’être visibles.
NB : N’oubliez pas de définir une taille à vos images, soit par attribut (width et height), soit par style CSS, pour éviter au navigateur de recalculer l’espace pris par l’image. En terme de web performance, si le navigateur doit recalculer la mise en page vous comprenez l’écueil (l’utilisateur risque de voir un effet “flip-flop” pas très agréable).
L’impact en terme de web performance a été mesuré par les équipes de WP-Rocket, plugin indispensable de WordPress. Pour résumer, le lazy loading natif permet sur les 2 pages testées de gagner entre 50% à 60% du poids des pages, alors que la solution JavaScript permet d’en gagner entre 60% à 80% (voir les résultats ici). Notez bien que l’impact est dépendant du nombre d’images dans la page. Dès lors, il est aisé pour les équipes de WP-Rocket de préconiser leur script de Lazy Loading, car aujourd’hui plus efficace que l’attribut loading avec la valeur lazy. Surtout qu’une solution JavaScript fonctionnera sur tous les navigateurs.
Lazy Loading selon artwaï
Pensant voir un gain significatif sans avoir rien à ajouter, la nouvelle gestion du chargement des images de Chrome 76 nous a déçu concernant notre site artwai.com. En ayant compris la notion des seuils de distance, et vu la configuration du site de notre agence web sur Rennes, on comprend mieux pourquoi. Dès lors, parce qu’on est curieux et très joueurs, nous n’avons pas hésité une seconde à mettre l’attribut loading avec la valeur lazy :
- sur toutes les vignettes d’articles pour les pages de listes (blog, recherche, etc…),
- sur les images bien en dessous de la ligne de flottaison,
- et sur les images dans le menu déployé.
Le résultat est plutôt intéressant puisque sur une page de listing on économise environ un tiers du poids de la page avant de scroller. Mais vous pourriez vous poser la question, est-ce qu’on vous encourage à en faire autant ?
Support dans les navigateurs
Techniquement le support de l’attribut loading est à ce jour limité à Chrome, comme l’indique caniuse.com :
Donc selon nos dernières stats, on ne s’adresse “qu’à 60%” des utilisateurs tout devices confondus.
2 cas à distinguer
Ensuite, reste à connaitre la nature des contenus. En effet si votre site contient une multitude d’images, il est plus intéressant d’utiliser un Lazy Loading en JavaScript, comme l’a démontré WP-Rocket.
A l’inverse, si le site est déjà bien optimisé sans solution de Lazy Loading et qu’il comporte peu d’images (le site artwai.com est dans ce cas là) alors oui, foncez ! Placez cet attribut loading avec la valeur lazy là où cela est judicieux.
Surtout oubliez les solutions hybrides !
Ce qui est vrai aujourd’hui ne le sera plus demain. N’oubliez pas que l’équipe de Chrome continue d’améliorer le comportement de son navigateur pour affiner le chargement des images et même sans attribut. Tous les navigateurs dérivés de Chromium vont bénéficier de cette nouvelle technique. Firefox, si on en croit zdnet.com, devrait l’implémenter d’ici un an. Bref, il va falloir être patient avant de généraliser cet attribut, mais le chemin est tracé. Et nous n’avons plus qu’à le suivre…
Photo par Sebastian Molinares via Unsplash