Dans cet atelier de programmation, vous allez implémenter le préchargement de deux manières: avec <link rel="prefetch">
et avec l'en-tête HTTP Link
.
L'application exemple est un site Web qui comporte une page de destination promotionnelle avec une remise spéciale sur le t-shirt le plus vendu de la boutique. Étant donné que la page de destination renvoie vers un seul produit, on peut supposer qu'un pourcentage élevé d'utilisateurs accèdera à la page d'informations détaillées sur le produit. Cela fait de la page du produit un candidat idéal pour le préchargement sur la page de destination.
Évaluer les performances
Commencez par établir les performances de référence:
- Cliquez sur Remixer pour modifier pour rendre le projet modifiable.
- Pour prévisualiser le site, appuyez sur Afficher l'application, puis sur Plein écran .
- Appuyez sur Ctrl+Maj+J (ou Cmd+Option+J sur Mac) pour ouvrir DevTools.
Cliquez sur l'onglet Réseau.
Dans la liste déroulante Limitation, sélectionnez 3G rapide pour simuler un type de connexion lent.
Pour charger la page du produit, cliquez sur Buy now (Acheter maintenant) dans l'application exemple.
Le chargement de la page product-details.html
prend environ 600 ms:
Précharger la page produit avec <link rel="prefetch">
Pour améliorer la navigation, insérez une balise prefetch
sur la page de destination afin de précharger la page product-details.html
:
- Ajoutez l'élément
<link>
suivant à l'en-tête du fichierviews/index.html
:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
<link rel="prefetch" href="/product-details.html" as="document">
...
</head>
L'attribut as
est facultatif, mais recommandé. Il aide le navigateur à définir les en-têtes appropriés et à déterminer si la ressource se trouve déjà dans le cache. Exemples de valeurs pour cet attribut: document
, script
, style
, font
, image
et autres.
Pour vérifier que le préchargement fonctionne:
- Pour prévisualiser le site, appuyez sur Afficher l'application, puis sur Plein écran .
- Appuyez sur Ctrl+Maj+J (ou Cmd+Option+J sur Mac) pour ouvrir les outils de développement.
Cliquez sur l'onglet Réseau.
Dans la liste déroulante Limitation, sélectionnez 3G rapide pour simuler un type de connexion lent.
Décochez la case Désactiver le cache.
Actualisez l'application.
Lorsque la page de destination se charge, la page product-details.html
se charge également, mais avec la priorité la plus basse:
La page est conservée dans le cache HTTP pendant cinq minutes, après quoi les règles Cache-Control
normales du document s'appliquent. Dans ce cas, product-details.html
possède un en-tête cache-control
avec une valeur de public, max-age=0
, ce qui signifie que la page est conservée pendant cinq minutes au total.
Réévaluer les performances
- Actualisez l'application.
- Pour charger la page produit, cliquez sur Acheter dans l'application exemple.
Examinez le panneau Network (Réseau). Il existe deux différences par rapport à la trace réseau initiale:
- La colonne Taille indique "cache de préchargement", ce qui signifie que cette ressource a été récupérée à partir du cache du navigateur plutôt que du réseau.
- La colonne Temps indique que le temps de chargement du document est désormais d'environ 10 ms.
Cela représente une réduction d'environ 98% par rapport à la version précédente, qui prenait environ 600 ms.
Bonus: Utiliser prefetch
comme amélioration progressive
Le préchargement est mieux implémenté en tant qu'amélioration progressive pour les utilisateurs qui naviguent sur des connexions rapides. Vous pouvez utiliser l'API Network Information pour vérifier les conditions du réseau et injecter dynamiquement des balises de préchargement en fonction de ces conditions. De cette façon, vous pouvez minimiser la consommation de données et réduire les coûts pour les utilisateurs ayant un forfait Internet lent ou coûteux.
Pour implémenter le préchargement adaptatif, commencez par supprimer la balise <link rel="prefetch">
de views/index.html
:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
<link rel="prefetch" href="/product-details.html" as="document">
...
</head>
Ajoutez ensuite le code suivant à public/script.js
pour déclarer une fonction qui injecte la balise prefetch
de manière dynamique lorsque l'utilisateur dispose d'une connexion rapide:
function injectLinkPrefetchIn4g(url) {
if (window.navigator.connection.effectiveType === '4g') {
//generate link prefetch tag
const linkTag = document.createElement('link');
linkTag.rel = 'prefetch';
linkTag.href = url;
linkTag.as = 'document';
//inject tag in the head of the document
document.head.appendChild(linkTag);
}
}
La fonction fonctionne comme suit:
- Il vérifie la propriété effectiveType de l'API Network Information pour déterminer si l'utilisateur utilise une connexion 4G (ou plus rapide).
- Si cette condition est remplie, une balise
<link>
est générée avecprefetch
comme type d'indice, l'URL qui sera préchargée est transmise dans l'attributhref
, et la ressource est indiquée comme étant undocument
HTML dans l'attributas
. - Enfin, il injecte le script dynamiquement dans le
head
de la page.
Ajoutez ensuite script.js
à views/index.html
, juste avant la balise de fermeture </body>
:
<body>
...
<script src="/script.js"></script>
</body>
Demander script.js
à la fin de la page garantit qu'il sera chargé et exécuté après l'analyse et le chargement de la page.
Pour vous assurer que le préchargement n'interfère pas avec les ressources critiques de la page actuelle, ajoutez l'extrait de code suivant pour appeler injectLinkPrefetchIn4g()
sur l'événement window.load
:
<body>
...
<script src="/script.js"></script>
<script>
window.addEventListener('load', () => {
injectLinkPrefetchIn4g('/product-details.html');
});
</script>
</body>
Désormais, la page de destination ne précharge product-details.html
que les connexions rapides. Pour vérifier que:
- Pour prévisualiser le site, appuyez sur Afficher l'application, puis sur Plein écran .
- Appuyez sur Ctrl+Maj+J (ou Cmd+Option+J sur Mac) pour ouvrir DevTools.
- Cliquez sur l'onglet Réseau.
- Dans la liste déroulante Limitation, sélectionnez En ligne.
- Actualisez l'application.
product-details.html
doit s'afficher dans le panneau "Network" (Réseau) :
Pour vérifier que la page produit n'est pas préchargée sur les connexions lentes:
- Dans la liste déroulante "Limitation", sélectionnez 3G lente.
- Actualisez l'application.
Le panneau Network ne doit inclure que les ressources de la page de destination sans product-details.html
:
Prélire la feuille de style de la page produit avec l'en-tête HTTP Link
L'en-tête HTTP Link
peut être utilisé pour précharger le même type de ressources que la balise link
. Le choix du moment où utiliser l'une ou l'autre dépend principalement de vos préférences, car la différence de performances est insignifiante. Dans ce cas, vous l'utiliserez pour précharger le CSS principal de la page produit, afin d'améliorer encore son affichage.
Ajoutez un en-tête HTTP Link
pour style-product.css
dans la réponse du serveur pour la page de destination:
- Ouvrez le fichier
server.js
et recherchez le gestionnaireget()
pour l'URL racine:/
. - Ajoutez la ligne suivante au début du gestionnaire:
app.get('/', function(request, response) {
response.set('Link', '</style-product.css>; rel=prefetch');
response.sendFile(__dirname + '/views/index.html');
});
- Pour prévisualiser le site, appuyez sur Afficher l'application, puis sur Plein écran .
- Appuyez sur Ctrl+Maj+J (ou Cmd+Option+J sur Mac) pour ouvrir DevTools.
- Cliquez sur l'onglet Réseau.
- Actualisez l'application.
L'style-product.css
est désormais préchargé avec la priorité la plus faible après le chargement de la page de destination:
Pour accéder à la page du produit, cliquez sur Acheter maintenant. Examinez le panneau Network (Réseau) :
Le fichier style-product.css
est extrait du "cache de préchargement" et n'a mis que 12 ms à se charger.