Deux méthodes de préchargement : balises <link> et en-têtes HTTP

Demián Renzulli
Demián Renzulli

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 possède une page de destination promotionnelle offrant une remise spéciale sur le t-shirt le plus vendu du magasin. Étant donné que la page de destination renvoie vers un seul produit, on peut supposer qu'un pourcentage élevé d'utilisateurs accéderont à la page d'informations détaillées sur le produit. Cela fait de la page produit un excellent candidat pour le préchargement sur la page de destination.

Évaluer les performances

Commencez par établir les performances de référence:

  1. Cliquez sur Remix to Edit (Remixer pour modifier) pour rendre le projet modifiable.
  2. Pour prévisualiser le site, appuyez sur Afficher l'application, puis sur Plein écran plein écran.
  3. Appuyez sur Ctrl+Maj+J (ou Cmd+Option+J sur Mac) pour ouvrir les outils de développement.
  4. Cliquez sur l'onglet Réseau.

  5. Dans la liste déroulante Limitation, sélectionnez 3G rapide pour simuler un type de connexion lente.

  6. Pour charger la page du produit, cliquez sur Acheter dans l'application exemple.

Le chargement de la page product-details.html prend environ 600 ms:

Panneau &quot;Réseau&quot; affichant les temps de chargement des fichiers product-details.html

Pour améliorer la navigation, insérez une balise prefetch dans la page de destination pour précharger la page product-details.html:

  • Ajoutez l'élément <link> suivant à l'en-tête du fichier 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>

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. Voici quelques exemples de valeurs pour cet attribut: document, script, style, font, image et others.

Pour vérifier que le préchargement fonctionne:

  1. Pour prévisualiser le site, appuyez sur Afficher l'application, puis sur Plein écran plein écran.
  2. Appuyez sur Ctrl+Maj+J (ou Cmd+Option+J sur Mac) pour ouvrir les outils de développement.
  3. Cliquez sur l'onglet Réseau.

  4. Dans la liste déroulante Limitation, sélectionnez 3G rapide pour simuler un type de connexion lente.

  5. Décochez la case Désactiver le cache.

  6. Actualisez l'application.

Désormais, lors du chargement de la page de destination, la page product-details.html se charge également, mais avec la priorité la plus faible:

Panneau &quot;Réseau&quot; affichant les product-details.html produits préchargés.

La page est conservée dans le cache HTTP pendant cinq minutes, au terme desquelles les règles Cache-Control normales du document s'appliquent. Dans ce cas, product-details.html comporte 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

  1. Actualisez l'application.
  2. Pour charger la page du produit, cliquez sur Acheter dans l'application exemple.

Consultez le panneau Network (Réseau). Il existe deux différences par rapport à la trace réseau initiale:

  • La colonne Taille affiche "Cache de préchargement", ce qui signifie que la ressource a été récupérée à partir du cache du navigateur et non 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 a pris environ 600 ms.

Panneau réseau affichant le fichier product-details.html récupéré du cache de préchargement.

Crédit supplémentaire: utilisez prefetch comme amélioration progressive

Le préchargement est mieux mis en œuvre en tant qu'amélioration progressive pour les utilisateurs qui utilisent une connexion rapide. Vous pouvez utiliser l'API Network Information pour vérifier les conditions du réseau et en fonction de cette injection dynamique de tags de préchargement. Ainsi, vous pouvez réduire la consommation de données et les coûts pour les utilisateurs dont les forfaits Internet sont lents ou coûteux.

Pour implémenter le préchargement adaptatif, commencez par supprimer le tag <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 dynamiquement la balise prefetch 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);
    }
}

Cette fonction fonctionne comme suit:

  • Elle vérifie la propriété effectiveType de l'API Network Information pour déterminer si l'utilisateur est connecté à une connexion 4G (ou plus rapide).
  • Si cette condition est remplie, il génère une balise <link> avec le type d'indice prefetch, transmet l'URL qui sera préchargée dans l'attribut href et indique que la ressource est un document HTML dans l'attribut as.
  • Enfin, il injecte le script de manière dynamique dans la section 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'elle sera chargée et exécutée 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>

La page de destination ne précharge désormais product-details.html que pour les connexions rapides. Pour vérifier que:

  1. Pour prévisualiser le site, appuyez sur Afficher l'application, puis sur Plein écran plein écran.
  2. Appuyez sur Ctrl+Maj+J (ou Cmd+Option+J sur Mac) pour ouvrir les outils de développement.
  3. Cliquez sur l'onglet Réseau.
  4. Dans la liste déroulante Throttling (Limitation), sélectionnez Online (En ligne).
  5. Actualisez l'application.

product-details.html devrait s'afficher dans le panneau "Network" (Réseau) :

Panneau &quot;Réseau&quot; affichant les product-details.html produits préchargés.

Pour vérifier que la page du produit n'est pas préchargée lorsque la connexion est lente:

  1. Dans la liste déroulante "Limitation", sélectionnez 3G lente.
  2. Actualisez l'application.

Le panneau Network ne doit inclure que les ressources de la page de destination sans product-details.html:

Panneau &quot;Réseau&quot; indiquant que le fichier product-details.html n&#39;est pas préchargé.

L'en-tête HTTP Link peut être utilisé pour précharger le même type de ressources que le tag link. La différence de performances n'est pas significative lorsque vous choisissez quand utiliser l'une ou l'autre de ces options, en fonction de vos préférences. Dans ce cas, utilisez-le 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:

  1. Ouvrez le fichier server.js et recherchez le gestionnaire get() pour l'URL racine: /.
  2. 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');
});
  1. Pour prévisualiser le site, appuyez sur Afficher l'application, puis sur Plein écran plein écran.
  2. Appuyez sur Ctrl+Maj+J (ou Cmd+Option+J sur Mac) pour ouvrir les outils de développement.
  3. Cliquez sur l'onglet Réseau.
  4. Actualisez l'application.

Le style-product.css est désormais préchargé avec la priorité la plus basse après le chargement de la page de destination:

Panneau &quot;Réseau&quot; affichant le fichier style-product.css préchargé

Pour accéder à la page du produit, cliquez sur Acheter. Examinez le panneau Network (Réseau) :

Panneau &quot;Réseau&quot; affichant le fichier style-product.css récupéré depuis le cache de préchargement

Le fichier style-product.css est récupéré à partir du "cache de préchargement". Son chargement n'a pris que 12 ms.