Chargement des pages plus rapide grâce à l'utilisation du temps de réflexion du serveur avec les premiers conseils

Découvrez comment votre serveur peut envoyer des indications au navigateur à propos des sous-ressources critiques.

Kenji Bace
Kenji Baheux

Qu'est-ce que l'option Early Hints ?

Les sites Web sont devenus plus sophistiqués au fil du temps. Ainsi, il n'est pas rare qu'un serveur doive effectuer des tâches importantes (par exemple, l'accès aux bases de données ou aux CDN accédant au serveur d'origine) pour produire le code HTML de la page demandée. Malheureusement, ce "temps de réflexion du serveur" entraîne une latence supplémentaire avant que le navigateur ne commence à afficher la page. En effet, la connexion reste inactive tant qu'il faut au serveur pour préparer la réponse.

Image montrant un intervalle de temps de réflexion de 200 ms entre le chargement de la page et le chargement des autres ressources.
Sans Early Hints: tout est bloqué sur le serveur, ce qui détermine la manière de répondre pour la ressource principale.

Le champ "Early Hints" est un code d'état HTTP (103 Early Hints) utilisé pour envoyer une réponse HTTP préliminaire avant une réponse finale. Cela permet à un serveur d'envoyer au navigateur des indications concernant les sous-ressources critiques (par exemple, la feuille de style de la page, le code JavaScript critique) ou les origines susceptibles d'être utilisées par la page, pendant que le serveur est en train de générer la ressource principale. Le navigateur peut utiliser ces suggestions pour préchauffer les connexions et demander des sous-ressources, en attendant la ressource principale. En d'autres termes, cette fonctionnalité permet au navigateur de profiter de ce temps de réflexion sur le serveur en acquérant un peu d'avance, et en accélérant ainsi le chargement des pages.

Image montrant comment la fonctionnalité Early Hints permet à la page d'envoyer une réponse partielle.
Avec les premiers indices: le serveur peut diffuser une réponse partielle avec des indices de ressources pendant qu'il détermine la réponse finale

Dans certains cas, l'amélioration des performances du Largest Contentful Paint peut passer de quelques centaines de millisecondes, comme observé par Shopify et Cloudflare, et jusqu'à une seconde plus vite, comme illustré dans cette comparaison avant/après:

Comparaison de deux sites.
Comparaison avant/après des premiers indices sur un site Web test avec WebPageTest (Moto G4 – DSL)

Implémenter les premiers indices

Avant d'approfondir le sujet, notez que les premiers conseils ne sont pas utiles si votre serveur peut envoyer immédiatement un code 200 (ou toute autre réponse finale). Dans ce cas, envisagez plutôt d'utiliser les valeurs standards link rel=preload ou link rel=preconnect dans la réponse principale (en-tête HTTP Link rel) ou dans la réponse principale (éléments <link>). Si votre serveur a besoin d'un peu de temps pour générer la réponse principale, poursuivez votre lecture.

Pour bénéficier de cette fonctionnalité, la première étape consiste à identifier les principales pages de destination, c'est-à-dire les pages auxquelles commencent généralement les utilisateurs lorsqu'ils visitent votre site Web. Il peut s'agir de la page d'accueil ou des pages de fiches produit populaires si de nombreux utilisateurs viennent d'autres sites Web. Ces points d'entrée sont plus importants que les autres pages, car l'utilité d'Early Hints diminue à mesure que l'utilisateur navigue sur votre site Web. En d'autres termes, le navigateur est plus susceptible de disposer de toutes les sous-ressources dont il a besoin lors de la deuxième ou troisième navigation suivante. C'est aussi toujours une bonne idée de faire une excellente première impression !

Maintenant que vous disposez de cette liste de pages de destination hiérarchisées, l'étape suivante consiste à identifier les origines ou sous-ressources qui conviendraient le mieux aux indications de préconnexion ou de préchargement, en tant que première approximation. Il s'agit généralement des origines et des sous-ressources qui contribuent le plus aux métriques utilisateur clés, telles que Largest Contentful Paint ou First Contentful Paint. Plus concrètement, recherchez des sous-ressources qui bloquent l'affichage, telles que du code JavaScript synchrone, des feuilles de style ou même des polices Web. De même, recherchez les origines qui hébergent des sous-ressources qui contribuent grandement aux métriques utilisateur clés. Remarque: Si vos ressources principales utilisent déjà <link rel=preconnect> ou <link rel=preload>, vous pouvez envisager ces origines ou ressources parmi les candidats aux premiers indices. Pour en savoir plus, consultez cet article.

La deuxième étape consiste à réduire le risque d'utilisation de cette fonctionnalité sur les ressources ou les origines susceptibles d'être obsolètes ou qui ne sont plus utilisées par la ressource principale. Par exemple, les ressources qui sont fréquemment mises à jour et gérées par version (par exemple, example.com/css/main.fa231e9c.css) ne constituent pas forcément le meilleur choix. Notez que ce problème n'est pas spécifique aux alertes précoces. Il s'applique à tous les liens rel=preload ou rel=preconnect, où qu'ils soient. Il s'agit du type de détail le mieux adapté à l'automatisation ou à la création de modèles. Par exemple, un processus manuel est plus susceptible d'entraîner des incohérences au niveau des URL de hachage ou de version entre link rel=preload et la balise HTML réelle utilisant la ressource.

À titre d'exemple, considérez le flux suivant:

GET /main.html
Host: example.com
User-Agent: [....] Chrome/103.0.0.0 [...]

Le serveur prédit que main.abcd100.css sera nécessaire et suggère de le précharger via les premiers indices:

103 Early Hints
Link: </main.abcd100.css>; rel=preload; as=style
[...]

Quelques instants plus tard, la page Web s'affiche, y compris le CSS associé. Malheureusement, cette ressource CSS est fréquemment mise à jour, et la ressource principale a déjà cinq versions en avance (abcd105) par rapport à la ressource CSS prédite (abcd100).

200 OK
[...]
<HTML>
<head>
   <title>Example</title>
   <link rel="stylesheet" href="/main.abcd105.css">

En règle générale, visez des ressources et des origines relativement stables et largement indépendantes du résultat de la ressource principale. Si nécessaire, vous pouvez envisager de diviser vos ressources de clé en deux: une partie stable conçue pour être utilisée avec les premiers indices et une partie plus dynamique à extraire une fois la ressource principale reçue par le navigateur:

<HTML>
<head>
   <title>Example</title>
   <link rel="stylesheet" href="/main.css">
   <link rel="stylesheet" href="/experimental.3eab3290.css">

Enfin, côté serveur, recherchez les principales demandes de ressources envoyées par des navigateurs connus pour prendre en charge cette fonctionnalité, puis répondez immédiatement avec le code "103 Early Hints". Dans la réponse 103, incluez les indications de préconnexion et de préchargement pertinentes. Une fois que la ressource principale est prête, poursuivez avec la réponse habituelle (par exemple, "200 OK" en cas de réussite). Pour assurer la rétrocompatibilité, il est recommandé d'inclure également les en-têtes HTTP Link dans la réponse finale, et peut-être même de l'enrichir avec des ressources critiques devenues évidentes lors de la génération de la ressource principale (par exemple, la partie dynamique d'une ressource de clé si vous avez suivi la suggestion de répartition en deux). Le résultat se présente comme suit:

GET /main.html
Host: example.com
User-Agent: [....] Chrome/103.0.0.0 [...]
103 Early Hints
Link: <https://fonts.google.com>; rel=preconnect
Link: </main.css>; rel=preload; as=style
Link: </common.js>; rel=preload; as=script

Quelques instants plus tard:

200 OK
Content-Length: 7531
Content-Type: text/html; charset=UTF-8
Content-encoding: br
Link: <https://fonts.google.com>; rel=preconnect
Link: </main.css>; rel=preload; as=style
Link: </common.js>; rel=preload; as=script
Link: </experimental.3eab3290.css>; rel=preload; as=style
<HTML>
<head>
   <title>Example</title>
   <link rel="stylesheet" href="/main.css">
   <link rel="stylesheet" href="/experimental.3eab3290.css">
   <script src="/common.js"></script>
   <link rel="preconnect" href="https://fonts.googleapis.com">

Prise en charge des navigateurs

Bien que l'option "Early Hints" (103) soit compatible avec tous les principaux navigateurs, les instructions qui peuvent être envoyées dans ce type de notification diffèrent selon les navigateurs:

Compatibilité avec la préconnexion:

Navigateurs pris en charge

  • 103
  • 103
  • 120
  • 17

Compatibilité avec le préchargement:

Navigateurs pris en charge

  • 103
  • 103
  • x

Support serveur

Voici un bref récapitulatif de la compatibilité des Early Hints avec les logiciels de serveur HTTP Open Source les plus utilisés:

Activer les indications rapides en toute simplicité

Si vous utilisez l'une des plates-formes ou l'un des CDN suivants, vous n'aurez peut-être pas besoin d'implémenter manuellement les premiers conseils. Consultez la documentation en ligne de votre fournisseur de solutions pour savoir s'il est compatible avec les premiers indicateurs, ou consultez la liste non exhaustive disponible ici:

Éviter les problèmes pour les clients qui n'acceptent pas les premiers conseils

Les réponses HTTP informatives de la plage 100 font partie de la norme HTTP. Toutefois, certains robots ou clients plus anciens peuvent rencontrer des difficultés avec ces réponses, car avant le lancement de 103 Eary Hints, elles étaient rarement utilisées pour la navigation générale sur le Web.

L'émission d'indications précoces 103 en réponse aux clients qui envoient un en-tête de requête HTTP sec-fetch-mode: navigate doit garantir que ces indications ne sont envoyées que pour les clients plus récents qui savent attendre la réponse suivante. De plus, comme les indications précoces ne sont compatibles qu'avec les requêtes de navigation (voir les limites actuelles), elles ont l'avantage d'éviter de les envoyer inutilement pour d'autres requêtes.

En outre, il est recommandé de n'envoyer les alertes via des connexions HTTP/2 ou HTTP/3 que via des connexions HTTP/2 ou HTTP/3.

Format avancé

Si vous avez entièrement appliqué les indications précoces à vos principales pages de destination et que vous recherchez d'autres opportunités, le schéma avancé suivant peut vous intéresser.

Pour les visiteurs qui effectuent leur ne demande de page dans le cadre d'un parcours utilisateur typique, vous pouvez adapter la réponse "Early Hints" au contenu qui se trouve plus bas et plus profond sur la page. Autrement dit, vous pouvez utiliser cette fonctionnalité sur des ressources moins prioritaires. Cela peut sembler contre-intuitif, car nous vous recommandons de vous concentrer sur les sous-ressources ou les origines à priorité élevée qui bloquent l'affichage. Toutefois, si un visiteur a navigué pendant un certain temps, il est très probable que son navigateur dispose déjà de toutes les ressources essentielles. À partir de là, il peut être judicieux de concentrer votre attention sur les ressources de moindre priorité. Il peut s'agir, par exemple, d'utiliser les premiers conseils pour charger des images de produits ou de code JS/CSS supplémentaire qui ne sont nécessaires que pour les interactions utilisateur moins courantes.

Limites actuelles

Voici les limites liées aux indications précoces, telles qu'elles sont implémentées dans Chrome:

  • Uniquement disponible pour les requêtes de navigation (c'est-à-dire la ressource principale du document de premier niveau).
  • Prend uniquement en charge preconnect et preload (c'est-à-dire que prefetch n'est pas accepté).
  • Lorsqu'un indice précoce est suivi d'une redirection multi-origine au niveau de la réponse finale, Chrome supprime les ressources et les connexions obtenues par le biais des premiers conseils.

Les autres navigateurs présentent des limites similaires et l'envoi des premiers indices 103 à preconnect uniquement.

Étape suivante

En fonction de l'intérêt de la communauté, nous pouvons améliorer notre mise en œuvre des premiers conseils avec les fonctionnalités suivantes:

  • Indices précoces envoyés lors des requêtes de sous-ressources.
  • Indications anticipées envoyées sur les demandes de ressources principales de l'iFrame.
  • Prise en charge du préchargement dans les premiers indices.

N'hésitez pas à nous faire part de vos commentaires sur les aspects à prioriser et sur la façon d'améliorer encore cette fonctionnalité.

Relation avec H2/Push

Si vous connaissez la fonctionnalité obsolète HTTP2/Push, vous vous demandez peut-être en quoi cette fonctionnalité diffère. Alors que l'option "Early Hints" nécessite un aller-retour pour que le navigateur commence à récupérer les sous-ressources critiques, avec HTTP2/Push, le serveur peut commencer à transmettre des sous-ressources avec la réponse. Bien que cela semble incroyable, cela a entraîné un inconvénient structurel majeur: avec HTTP2/Push, il était extrêmement difficile d'éviter de transmettre des sous-ressources dont le navigateur disposait déjà. Cet effet de "super poussée" a conduit à une utilisation moins efficace de la bande passante réseau, ce qui a considérablement fragilisé les gains de performances. De manière générale, les données Chrome ont montré que les protocoles HTTP2 et Push ont en fait un impact négatif sur les performances sur le Web.

En revanche, cette fonctionnalité est plus efficace dans la pratique, car elle associe la possibilité d'envoyer une réponse préliminaire à des indications qui laissent au navigateur se charger de récupérer les informations dont il a réellement besoin ou de s'y connecter. Bien qu'Early Hints ne couvre pas tous les cas d'utilisation théoriques à l'aide des protocoles HTTP2 et Push, nous pensons qu'il s'agit d'une solution plus pratique pour accélérer la navigation.

Vignette de Pierre Bamin.