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 au navigateur des indications concernant les sous-ressources critiques.

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

Les sites Web sont devenus de plus en plus sophistiqués au fil du temps. Ainsi, il n'est pas rare qu'un serveur ait besoin d'effectuer des tâches complexes (par exemple, l'accès aux bases de données ou les 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 du serveur de 200 ms entre le chargement de la page et le chargement des autres ressources
Sans avertissement préalable: tout est bloqué sur le serveur, ce qui détermine la manière de répondre pour la ressource principale.

Le terme "Early Hints" correspond à 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, les feuilles 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éparer les connexions et demander des sous-ressources, en attendant la ressource principale. En d'autres termes, cette fonctionnalité aide le navigateur à tirer parti de ce "temps de réflexion du serveur" en accompagnant un travail à l'avance, ce qui accélère le chargement des pages.

Image montrant comment la fonctionnalité Early Hints permet à la page d'envoyer une réponse partielle.
Avec les indications anticipées: le serveur peut diffuser une réponse partielle avec des indications de ressources le temps de déterminer la réponse finale

Dans certains cas, l'amélioration des performances de la métrique Largest Contentful Paint peut aller de quelques centaines de millisecondes, comme l'observe Shopify et par Cloudflare, et jusqu'à une seconde plus vite, comme le montre cette comparaison avant et après:

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

Utiliser les indications précoces

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

Maintenant que vous disposez de cette liste de pages de destination classées par ordre de priorité, l'étape suivante consiste à identifier les origines ou les sous-ressources adaptées à preconnect ou preload. Il s'agit généralement des origines et des sous-ressources qui contribuent le plus aux métriques utilisateur clés, comme 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.

Notez également que si vos ressources principales utilisent déjà preconnect ou preload, vous pouvez envisager ces origines ou ressources parmi les candidats aux premiers indices. Pour en savoir plus, découvrez comment optimiser le LCP. Toutefois, copier naïvement les instructions preconnect et preload depuis HTML vers les premiers indicateurs peut ne pas être optimal.

Lorsque vous les utilisez en HTML, il est généralement préférable d'ajouter des ressources preconnect ou preload que Preload Scanner ne détecte pas dans le code HTML (par exemple, des polices ou des images de fond qui seraient autrement découvertes tardivement). Pour les indications préalables, vous ne disposez pas du code HTML. À la place, vous pouvez preconnect vers des domaines critiques ou preload des ressources critiques qui seraient peut-être découvertes tôt dans le code HTML (par exemple, le préchargement de main.css ou app.js). De plus, tous les navigateurs ne sont pas compatibles avec preload pour les indications précoces. Consultez Compatibilité des navigateurs.

La deuxième étape consiste à réduire les risques liés à l'utilisation des premiers indices 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) peuvent ne pas être le meilleur choix. Notez que cette préoccupation n'est pas spécifique aux alertes précoces. Elle s'applique à toutes les preload ou preconnect, où qu'elles soient présentes. 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 une incohérence au niveau des URL de hachage ou de version entre preload et la balise HTML réelle utilisant la ressource.

Prenons l'exemple du 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 à l'aide des premiers indices:

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

Quelques instants plus tard, la page Web, y compris le CSS associé, s'affiche. Malheureusement, cette ressource CSS est fréquemment mise à jour, et la ressource principale est déjà en avance de cinq versions (abcd105) sur 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 conseils et une partie plus dynamique à récupérer après que le navigateur a reçu la ressource principale:

<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 les premiers indicateurs, et répondez immédiatement en envoyant le code 103. 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, fournissez 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, en les complétant éventuellement avec des ressources critiques devenues évidentes lors de la génération de la ressource principale (par exemple, la partie dynamique d'une ressource clé si vous avez suivi la suggestion de répartition en deux). Voici comment cela se présenterait:

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 la plupart des principaux navigateurs soient compatibles avec la fonctionnalité 103 Early Hints, les instructions pouvant être envoyées via un Early Hint diffèrent selon le navigateur:

Compatibilité avec la préconnexion:

Navigateurs pris en charge

  • 103
  • 103
  • 120
  • 17

Compatibilité avec le préchargement:

Navigateurs pris en charge

  • 103
  • 103
  • 123
  • x

Les outils pour les développeurs Chrome sont également compatibles avec 103 indices précoces.

Support serveur

Voici un bref récapitulatif de la compatibilité des premiers indices parmi les logiciels de serveur HTTP Open Source populaires:

Activez les indications anticipées plus facilement

Si vous utilisez l'un des CDN ou plates-formes suivants, vous n'aurez peut-être pas besoin d'implémenter manuellement les premiers conseils. Reportez-vous à 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 indications précoces

Les réponses HTTP informatives de la plage 100 font partie de la norme HTTP, mais certains bots 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.

Seule l'émission de 103 indications précoces en réponse aux clients qui envoient un en-tête de requête HTTP sec-fetch-mode: navigate permet de s'assurer que ces indications ne sont envoyées que pour les clients plus récents qui savent attendre la réponse suivante. De plus, étant donné que les premiers conseils ne sont compatibles qu'avec les requêtes de navigation (voir les limites actuelles), cela présente l'avantage d'éviter de les envoyer inutilement pour d'autres requêtes.

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

Schéma avancé

Si vous avez entièrement appliqué les premiers conseils à vos principales pages de destination et que vous êtes à la recherche d'autres opportunités, le schéma avancé suivant peut vous intéresser.

Pour les visiteurs qui se trouvent sur leur nth demande de page dans le cadre d'un parcours utilisateur standard, vous pouvez adapter la réponse des premiers indicateurs au contenu situé plus bas et plus profond sur la page, autrement dit utiliser les premiers indices sur les ressources de priorité inférieure. Cela peut sembler contre-intuitif, car nous vous recommandons de vous concentrer sur les sous-ressources ou origines à priorité élevée qui bloquent l'affichage. Toutefois, alors qu'un visiteur s'est connecté depuis 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é. Par exemple, vous pouvez utiliser des indications rapides pour charger des images de produits, ou utiliser des fichiers JS/CSS supplémentaires qui ne sont nécessaires que pour des interactions utilisateur moins courantes.

Limites actuelles

Voici les limites des premiers indicateurs tels qu'ils sont implémentés dans Chrome:

  • Disponible uniquement pour les requêtes de navigation (c'est-à-dire la ressource principale du document de premier niveau).
  • Compatible uniquement avec preconnect et preload (en d'autres termes, prefetch n'est pas accepté).
  • Lorsqu'un indice précoce est suivi d'une redirection multi-origine dans la réponse finale, Chrome supprime les ressources et les connexions obtenues à l'aide de cette fonctionnalité.

D'autres navigateurs présentent des limites similaires, et certains limitent davantage l'utilisation des 103 indications précoces à preconnect uniquement.

Étape suivante

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

  • Envoi d'indications précoces dans les requêtes de sous-ressources
  • Premières indications envoyées pour les demandes de ressources principales de l'iFrame.
  • Prise en charge du préchargement dans les premiers indicateurs.

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

Relation avec H2/Push

Si vous connaissez la fonctionnalité obsolète HTTP2/Push, vous vous demandez peut-être en quoi les indications précoces diffèrent. Alors que les premiers indicateurs nécessitent 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 en même temps que 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 transférer des sous-ressources dont le navigateur disposait déjà. Cet effet de "poussée excessive" a entraîné une utilisation moins efficace de la bande passante réseau, ce qui entraînait considérablement les avantages en termes de performances. Dans l'ensemble, les données Chrome ont montré que le protocole HTTP2/Push nuisait net aux performances sur le Web.

En revanche, dans la pratique, les indications anticipées sont plus performantes, car elles permettent 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 que cette fonctionnalité ne couvre pas tous les cas d'utilisation théoriques que les protocoles HTTP2 et push pourraient traiter, nous pensons qu'elle est une solution plus pratique pour accélérer la navigation.

Vignette de Pierre Bamin.