Niveau Niveau débutant

Les aides au préchargement de ressources

Articlehtml

Publié par le , mis à jour le (8608 lectures)

preload chargement defer async lazyloading fetchpriority parseur performances

Chaque navigateur web dispose d'un "parseur HTML" (un interpréteur) qui parcourt le code source et le transforme en modèle d'objets.

Ce parseur HTML du navigateur est bloqué par deux types de ressources :

  • les éléments <link>
  • les éléments <script> qui ne disposent pas d'attributs async ni defer
Illustration de bloquage du parseur HTML en raison d'un chargement de feuille de styles CSS (source : web.dev)

Depuis 2008, un second mécanisme parallèle entre en jeu sur l'ensemble des navigateurs : celui du "Preload Scanner". Ce second parseur agit lorsque le parseur HTML est bloqué sur une ressource et pré-charge les ressources suivantes indiquées dans le markup HTML.

Cela signifie que certains éléments placés hors HTML ne participeront pas à cette recherche anticipée : c'est le cas des polices et des images de fond appelées dans les fichiers CSS, mais également des liens ou ressources situées dans des scripts.

Ce mécanisme est automatique, mais il est possible de l'influencer en proposant le pré-chargement de certaines ressources en priorité en agissant sur les "Priority Hints" tels que async, defer, rel=preload ou fetchpriority

async et defer

Ces attributs sont liés au chargement des scripts. Dans les deux cas, ces attributs rendent le chargement asynchrone et ne bloquent pas le parseur HTML :

  • async est exécuté dès que le navigateur en a la possibilité. Les ressources sont potentiellement chargées dans n'importe quel ordre.
  • defer est exécuté lorsque tout le DOM est parsé. Les ressources sont chargées dans l'ordre dans lequel elles sont placées dans le DOM.
  • les <script module> (EcmaScript Modules) sont en defer par défaut.

Détail important : async est prioritaire sur defer.

<script async src="script.js">
<script defer src="script.js">

Pour en savoir plus à ce sujet, n'hésitez pas à consulter l'article détaillé "Les attributs async et defer pour <script>".

rel=preload

Cette déclaration demande au navigateur de découvrir et charger une ressource en priorité avant même que le parseur ne l'atteigne. Elle est également particulièrement utile pour tous les assets non indiqués dans le markup HTML.

Exemple de pré-chargement de police :

<!-- Dans le <head> après
     la feuille de styles pour ne pas la bloquer -->
<link rel="preload" as="font" href="kiwi.woff2" 
      type="font/woff2" crossorigin="anonymous">

(Note : ici crossorigin="anonymous" n'est utile que si la police n'est pas auto-hébergée)

Exemple de pré-chargement d'image :

<link rel="preload" as="image" href="hero.webp">

Priorité : le niveau de priorité de rel=preload est "Mandatory" (obligatoire), c'est à dire que cette fonctionnalité doit absolument être traitée en premier lieu par le navigateur. Cette action est susceptible de bloquer le chargement des feuilles de styles.

Pour mieux comprendre cette propriété dans un cas concret (polices de caractères), n'hésitez pas à consulter l'article détaillé "Optimisez vos polices web".

fetchpriority

L'attribut fetchpriority informe le navigateur du degré de priorité du pré-chargement d'une ressource. Il est possible de l'appliquer sur l'élément <link> mais aussi directement sur <img>, <script> et <iframe>.

Les valeurs possibles sont "high" (haute priorité), "low" (basse priorité) et "auto" (valeur par défaut).

Quelques exemples :

<!-- Ce script doit être pré-chargé 
     mais d'autres ressources sont prioritaires -->
<link rel="preload" href="script.js" as="script" fetchpriority="low">

<!-- Cette image de fond critique 
     est hautement prioritaire -->
<link rel="preload" as="image" href="hero.webp" fetchpriority="high">

<!-- Cette image doit être pré-chargée
     mais n'est pas vraiment critique -->
<img src="sausage.svg" alt="je ne suis pas importante" fetchpriority="low">

Avec l'exemple d'images d'un carousel :

<ul class="carousel">
  <img src="img/carousel-1.jpg" fetchpriority="high">
  <img src="img/carousel-2.jpg" fetchpriority="low">
  <img src="img/carousel-3.jpg" fetchpriority="low">
  <img src="img/carousel-4.jpg" fetchpriority="low">
</ul>

(source de l'exemple : https://web.dev/priority-hints/)

Priorité : le niveau de priorité de fetchpriority est "Hint" (indice), c'est à dire que cette fonctionnalité est une simple indication pour le navigateur.

preconnect et dns-prefetch

Ces attributs sont liés au chargement des ressources externes (non hébergées localement).

  • rel="preconnect" informe le navigateur que l'on souhaite établir une connexion le plus rapidement possible à une autre plateforme.
  • rel="dns-prefetch" ne fait que résoudre le nom de domaine sans toutefois atteindre la ressource indiquée.
<link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin>
<link rel="dns-prefetch" href="https://example.com">

Priorité : le niveau de priorité de preconnect et dns-prefetch est "Hint" (indice), c'est à dire que ces fonctionnalités sont de simples indications pour le navigateur.

Pour en savoir plus sur l'usage de ces attributs, n'hésitez pas à consulter l'article détaillé "Optimisation des pré-chargements avec prefetch, dns-prefetch et prerender".

Lazyloading

L'attribut loading permet de ne charger que les images situées au dessus de la ligne de flottaison. Les autres images ne sont alors chargées que lorsque cela devient nécessaire, au fur et à mesure que l'utilisateur scrolle (défile). On améliore ainsi le temps de chargement initial de la page.

Les valeurs de loading sont les suivantes :

  • eager : l'image est chargée immédiatement, qu'elle soit située dans ou hors de la fenêtre visible (valeur par défaut),
  • lazy : le chargement est retardé jusqu'à ce que l'usager scrolle et s'approche du bas de la fenêtre du navigateur.
<img src="image.webp" loading="lazy" width="" height="" alt="descriptif de l'image">
<iframe src="video-player.html" loading="lazy" title=""></iframe>

Pour en savoir plus sur cet attribut appliqué aux images, n'hésitez pas à consulter l'article détaillé "Attribut loading=lazy pour les images".

Commentaires

Si j'ai bien compris, le préchargement d'un carousel avec fetchpriority fait un peu double emploi avec le lazyload ?

À quoi bon le précharger alors que justement le lazyload s'en chargera, mais au bon moment.

En ce qui concerne les polices de caractère, en local ou en distant, on aurait plutôt intérêt à les charger en dernier, de façon à prioriser l'affichage de la page avec les polices système présentes. En mobile, ça devient crucial.

@Bongota :

Concernant le carrousel, le lazyload ne fournit aucune priorité quant à l'image à charger en premier, elles seront toutes chargées au même moment (même celles qui ne sont pas encore nécessaires).

Pour les polices de caractère, si tu charges ta police "exotique" tard, tu vas forcément créer un "Layout shift" (modification inopinée de l'affichage) et c'est justement ce qu'on voudrait éviter : https://web.dev/optimize-cls/

Bonjour,

je suis étonné de ton raisonnement sur le layzyload. Sur mon site onepage, j'ai plusieurs sliders, avec une image plocaceholder extrêmement légère en tête de chacun d'eux et à charger de toute façon. Quand je teste avec F12 et en mode réseau, je vois bien apparaître la première image du slider sur la console, quand on arrive à ce niveau de scroll. Si je descend plus bas dans la page, rien ne se passe au niveau des images du slider. Par contre, quand j'interviens sur ce slider pour avancer vers les images qu'il contient, elles apparaissent bien les unes après les autres sur la console F12. Comme si une détection lazyload se faisait alors horizontalement, à mon grand étonnement, mais aussi ma satisfaction.

D'accord pour les polices exotiques, même si le layout shift est bien moins important (je suppose sans l'avoir expérimenté pour des polices que pour des images dont on a pas donné les dimensions. À moins qu'on ait surchargé le site de polices exotiques.

Commenter

Vous devez être inscrit et identifié pour utiliser cette fonction.

Connectez-vous (déjà inscrit)

Oubli de mot de passe ? Pas de panique, on va le retrouver

Pas encore inscrit ? C'est très simple et gratuit.