rel="preload"
Baseline
Widely available
*
Cette fonctionnalité est bien établie et fonctionne sur de nombreux appareils et versions de navigateurs. Elle est disponible sur tous les navigateurs depuis janvier 2021.
* Certaines parties de cette fonctionnalité peuvent bénéficier de prise en charge variables.
La valeur preload
de l'attribut rel
de l'élément HTML <link>
permet de déclarer des requêtes à récupérer dans la partie <head>
du HTML de la page, en spécifiant les ressources dont votre page va avoir besoin dans peu de temps, et qu'il serait souhaitable de charger le plus tôt possible, avant que le rendu de la page par le navigateur ne commence. Cela permet de s'assurer que les ressources sont disponibles plus tôt et qu'elles auront moins de chances de bloquer le rendu de la page, ce qui améliore les performances.
Les bases
Pour charger un fichier CSS permettant de styler une page, on utilise le plus souvent l'élément <link>
de la manière suivante :
<link rel="stylesheet" href="styles/main.css" />
Ici, nous allons utiliser la valeur preload
sur l'attribut rel
, ce qui transformera l'élément <link>
en outil de préchargement utilisable pour n'importe quelle ressource. Nous devrons aussi indiquer :
Voici un exemple simple (voir nos fichiers JS et CSS d'exemple (angl.) et le résultat obtenu (angl.)) :
<head>
<meta charset="utf-8" />
<title>Exemple de préchargement JS et CSS</title>
<link rel="preload" href="style.css" as="style" />
<link rel="preload" href="main.js" as="script" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<h1>Balles rebondissantes</h1>
<canvas></canvas>
<script src="main.js" defer></script>
</body>
Dans l'exemple ci-dessus, nous préchargeons nos fichiers CSS et JavaScript afin qu'ils puissent être disponibles dès qu'ils sont nécessaires pour le rendu de la page. Cet exemple est trivial, car le navigateur va probablement découvrir en même temps les balises de préchargement, le <link rel="stylesheet">
et le <script>
, mais le bénéfice sera bien plus visible si les ressources sont plus nombreuses, plus lourdes et chargées à différents endroits. Par exemple :
- les ressources qui sont chargées depuis un fichier CSS, comme certaines polices et images ;
- les ressources inclues par des fichiers JavaScript, comme des fichiers JSON, d'autres scripts importés ou des services web ;
- les fichiers image et vidéos plus importants.
preload
dispose aussi d'autres avantages. L'utilisation de l'attribut as
pour spécifier le type de contenu à précharger permet au navigateur de :
- prioriser les ressources se chargeant avec davantage de précision ;
- les stocker dans le cache pour de futures requêtes, ce qui permet de réutiliser les ressources si c'est pertinent ;
- appliquer la bonne stratégie de sécurité du contenu aux ressources ;
- mettre en place les bons en-têtes de requêtes
Accept
pour les ressources.
Quels types de contenu peuvent être préchargés ?
De nombreux différents types de contenu peuvent être préchargés. Les valeurs possibles de l'attribut as
sont les suivantes :
fetch
: Ressource à récupérer via une requête fetch ou XHR, comme un ArrayBuffer, un binaire WebAssembly ou un fichier JSON.font
: Fichier de police.image
: Fichier image.script
: Fichier JavaScript.style
: Feuille de style CSS.track
: Fichier WebVTT.
Note :
Le préchargement des types font
et fetch
nécessite que l'attribut crossorigin
soit défini ; voir Préchargement avec CORS ci-dessous.
Note :
Pour plus de détails sur ces valeurs et les fonctionnalités web associées, consultez la spécification HTML — voir Link type "preload" (angl.). Notez aussi que la liste complète des valeurs acceptées par l'attribut as
est définie par la spécification Fetch — voir request destinations (angl.).
Inclure un type MIME
Les éléments <link>
peuvent accepter un attribut type
, qui contient le type MIME de la ressource ciblée. Cela est particulièrement utile lors du préchargement de ressources : le navigateur utilise la valeur de l'attribut type
pour déterminer s'il prend en charge cette ressource, et ne la télécharge que si c'est le cas, l'ignorant sinon.
<head>
<meta charset="utf-8" />
<title>Exemple de préchargement de vidéo</title>
<link rel="preload" href="sintel-short.mp4" as="video" type="video/mp4" />
</head>
<body>
<picture>
<source src="flower.avif" type="image/avif" />
<source src="flower.webp" type="image/webp" />
<img src="flower.jpg" />
</picture>
</body>
Le code de l'exemple ci-dessus fait que l'image image/avif
est préchargée uniquement dans les navigateurs qui la prennent en charge — et pour les utilisateur·ice·s qui ont la prise en charge de image/avif
dans leur navigateur, l'image image/avif
est effectivement utilisée (car c'est le premier <source>
indiqué). Cela rend le téléchargement de l'image probablement plus léger pour les utilisateur·ice·s qui ont la prise en charge de image/avif
dans leur navigateur.
Notez que pour les utilisateur·ice·s dont le navigateur prend en charge à la fois image/avif
et image/webp
, si dans ce code un élément <link rel="preload" href="flower.webp" as="image" type="image/webp">
était aussi indiqué, alors les deux images image/avif
et image/webp
seraient préchargées — même si une seule d'entre elles serait réellement utilisée.
Il est donc déconseillé d'indiquer le préchargement pour plusieurs types d'une même ressource. La bonne pratique est d'indiquer le préchargement uniquement pour le type que la majorité des utilisateur·ice·s va réellement utiliser. C'est pourquoi le code de l'exemple ci-dessus n'indique pas le préchargement pour l'image au format image/webp
.
Cependant, l'absence de préchargement n'empêche pas l'image image/webp
d'être réellement utilisée par celles et ceux qui en ont besoin : pour les utilisateur·ice·s dont le navigateur ne prend pas en charge image/avif
mais prend en charge image/webp
, le code de l'exemple ci-dessus fait toujours que l'image au format image/webp
est utilisée — mais cela se fait sans aussi indiquer le préchargement inutilement pour la majorité des autres utilisateur·ice·s.
Récupération de l'activation du CORS
Lors du préchargement des ressources analysées par des fonctions activant le CORS (partage des ressources entre origines multiples), comme par exemple fetch()
, XMLHttpRequest
ou fonts), une attention particulière doit être portée à la mise en place de l'attribut crossorigin
sur l'élément <link>
. L'attribut à besoin d'être mis en place pour faire correspondre le CORS de la ressource et le mode d'identification, même s'il ne s'agit pas d'une ressource ayant une origine différente de celle de la page.
Comme mentionné ci-dessus, un cas de figure intéressant est celui qui s'applique aux fichiers de polices. Pour plusieurs raisons, celles-ci doivent être analysées en utilisant le mode anonyme du CORS (voir cet article en anglais : Font fetching requirements (angl.)).
Voici un cas d'utilisation. Vous trouverez le code source complet sur GitHub (angl.) ainsi qu'une démonstration (angl.) :
<head>
<meta charset="utf-8" />
<title>Exemple de préchargement de police Web</title>
<link
rel="preload"
href="fonts/cicle_fina-webfont.woff2"
as="font"
type="font/woff2"
crossorigin />
<link
rel="preload"
href="fonts/zantroke-webfont.woff2"
as="font"
type="font/woff2"
crossorigin />
<link href="style.css" rel="stylesheet" />
</head>
<body>
…
</body>
En plus de fournir un type MIME avec l'attribut type
, ce code utilise un attribut crossorigin
afin de s'assurer que le préchargement du CORS correspond à la requête de chargement de la police.
Inclure des médias
Une autre belle fonctionnalité de l'élément <link>
concerne leur capacité à accepter les attributs media
. Il peut accepter les requêtes de types de médias ou encore des media queries complètes, ce qui vous permet de faire du préchargement responsive !
Voici un exemple. Vous pouvez consulter son code source sur GitHub (angl.) ou étudier un exemple de démonstration (angl.) :
<head>
<meta charset="utf-8" />
<title>Exemple de préchargement responsive</title>
<link
rel="preload"
href="bg-image-narrow.png"
as="image"
media="(width <= 600px)" />
<link
rel="preload"
href="bg-image-wide.png"
as="image"
media="(width > 600px)" />
<link rel="stylesheet" href="main.css" />
</head>
<body>
<header>
<h1>Mon site</h1>
</header>
<script>
const mediaQueryList = window.matchMedia("(width <= 600px)");
const header = document.querySelector("header");
if (mediaQueryList.matches) {
header.style.backgroundImage = 'url("bg-image-narrow.png")';
} else {
header.style.backgroundImage = 'url("bg-image-wide.png")';
}
</script>
</body>
Dans cet exemple nous incluons les attributs media
dans notre élément <link>
pour qu'une image plus fine soit préchargée si la personne visitant le site dispose d'un écran plus petit, et pour qu'une image plus large soit chargée sur les écrans plus larges. Pour cela, nous utilisons Window.matchMedia
et MediaQueryList
(consultez la page Tester les requêtes média en JavaScript pour en savoir plus).
Cela augmente les chances que la police sera disponible lors du rendu de la page, et diminue les risques de FOUT (pour flash of unstyled text, soit « flash de texte sans mis en forme » en français).
Il sera dommage de limiter le préchargement aux images, voyez plus loin ! On pourrait imaginer de précharger l'affichage d'un diagramme SVG si le visiteur se trouve sur un petit écran avec une bande passante ou une disponibilité CPU plus limitée, ou encore de précharger des morceaux de JavaScript complexes utilisés pour faire fonctionner une modélisation 3D interactive uniquement si les ressources du visiteur sont suffisantes.
Scripts et préchargement
Note :
Utilisez <link rel="modulepreload">
à la place si vous travaillez avec des modules JavaScript.
Un autre avantage de ces préchargements est que vous pouvez les exécuter avec un script.
Par exemple, ici nous créons une instance HTMLLinkElement
puis nous l'ajoutons au DOM :
const preloadLink = document.createElement("link");
preloadLink.href = "myscript.js";
preloadLink.rel = "preload";
preloadLink.as = "script";
document.head.appendChild(preloadLink);
Cela signifie que le navigateur va précharger le fichier myscript.js
, mais ne va pas réellement l'utiliser directement. Pour l'utiliser, vous pouvez faire ceci :
const preloadedScript = document.createElement("script");
preloadedScript.src = "myscript.js";
document.body.appendChild(preloadedScript);
C'est utile lorsque vous voulez précharger un script mais repousser son exécution au moment exact où vous en avez réellement besoin.
Spécifications
Specification |
---|
HTML> # link-type-preload> |
Compatibilité des navigateurs
Chargement…
Voir aussi
- Chargement spéculatif pour une comparaison entre
<link rel="preload">
et d'autres fonctionnalités similaires d'amélioration des performances. - « Preload : à quoi ça sert ? » (angl.) par Yoav Weiss