103 Early Hints en 2026 : Réduire le LCP avec le Préchargement Précoce
103 Early Hints laisse le serveur envoyer preload et preconnect avant le HTML final. Gains LCP de 100-400 ms sur SSR, avec configs Cloudflare, Vercel, Nginx et Node.js en 2026.
103 Early Hints est une réponse HTTP intermédiaire qui laisse le serveur envoyer des en-têtes Link: rel=preload et rel=preconnect au navigateur avant que la réponse finale 200 OK ne soit prête. Concrètement, pendant que votre origine calcule le HTML (requête base de données, rendu SSR, appel API), le navigateur télécharge déjà les CSS critiques, les polices et l'image LCP. En 2026, Cloudflare, Fastly, Vercel et Nginx 1.25+ supportent tous 103 en production. Sur mes propres déploiements, j'ai mesuré des gains LCP entre 120 ms et 400 ms sur des origines lentes.
103 Early Hints est une réponse HTTP informationnelle envoyée avant le 200 OK final, standardisée dans le RFC 8297.
Chrome, Edge et Opera supportent 103 depuis la version 103 (juin 2022). Firefox l'a activé par défaut en version 120 (novembre 2023). Safari 17.2 le supporte partiellement pour le preconnect.
Le gain LCP typique se situe entre 100 et 400 ms sur les pages avec un TTFB origine supérieur à 300 ms. Négligeable si votre TTFB est déjà sous 100 ms.
Cloudflare active 103 automatiquement via Smart Early Hints (analyse ML des pages passées) ; Vercel et Fastly exigent que vous les émettiez côté framework.
103 n'annule pas rel=preload dans le HTML : c'est complémentaire, mais 103 arrive plus tôt sur le fil.
Mesurez toujours le gain avec le RUM (LCP p75) et pas seulement WebPageTest, car le bénéfice dépend de la latence origine réelle de vos utilisateurs.
Qu'est-ce que 103 Early Hints ?
103 Early Hints est un code de statut HTTP informationnel (classe 1xx) qui autorise un serveur d'origine ou un CDN à envoyer une première réponse partielle contenant uniquement des en-têtes Link, avant d'envoyer la réponse finale 200 OK avec le corps HTML. Le navigateur reçoit ces indices, ouvre immédiatement les connexions TCP/TLS nécessaires, et lance le téléchargement des sous-ressources critiques pendant que le serveur continue à calculer la page.
Le mécanisme est standardisé dans le RFC 8297, publié en décembre 2017. Il exige HTTP/2 ou HTTP/3 : sur HTTP/1.1, une réponse 1xx bloque le pipeline et n'apporte aucun bénéfice. C'est d'ailleurs pour cette raison que le web a attendu que HTTP/2 dépasse 90 % de couverture avant que le mécanisme ne devienne réellement exploitable en production.
Prenons un exemple concret. Sur une page e-commerce dont le rendu SSR prend 450 ms côté origine, un 103 émis à 40 ms peut faire commencer le téléchargement de la police web principale et du CSS critique 400 ms plus tôt. Pour un LCP dominé par une image ou un webfont, le gain se retrouve directement dans la métrique Core Web Vitals.
Comment fonctionne le cycle de requête avec 103 ?
Sans 103, le navigateur envoie sa requête GET, puis attend l'intégralité de la réponse 200 OK avant de découvrir les <link rel="preload"> dans le <head>. Ce n'est qu'ensuite qu'il ouvre les connexions vers vos CDN images ou vos serveurs de polices. Chaque handshake TLS coûte typiquement 100 à 200 ms sur mobile 4G. C'est du temps mort pur.
Avec 103, le cycle devient :
Client Edge/Origin
|----- GET /product/42 ------>|
| | (démarre le SSR)
|<---- HTTP/2 103 -----------| (envoyé à ~30 ms)
| Link: </critical.css>; rel=preload; as=style
| Link: <https://cdn.example.com>; rel=preconnect
| |
|----- GET /critical.css ---->| (parallèle)
|----- TLS handshake cdn ---->|
| | (SSR terminé à ~420 ms)
|<---- HTTP/2 200 OK --------|
| <html>...</html> |
Le navigateur combine ensuite les deux flux : quand le HTML final arrive, le CSS critique est déjà dans le cache mémoire et l'image LCP est en cours de téléchargement. C'est cette parallélisation avec le temps de calcul serveur qui produit le gain.
Quels navigateurs supportent 103 Early Hints en 2026 ?
Au 2 septembre 2026, la couverture est excellente :
Navigateur
Support
Depuis version
Notes
Chrome / Chromium
Complet
103 (juin 2022)
preload + preconnect
Edge
Complet
103
Identique à Chrome
Opera
Complet
89
Identique à Chrome
Firefox
Complet
120 (nov 2023)
Activé par défaut
Safari (macOS/iOS)
Partiel
17.2 (déc 2023)
preconnect uniquement
Samsung Internet
Complet
21
Basé sur Chromium 103
Anciens navigateurs
Ignoré silencieusement
N/A
Aucune régression, 103 est simplement ignoré
Un point important. Les navigateurs qui ne comprennent pas 103 traitent la réponse intermédiaire comme un signal informationnel neutre et attendent le 200 OK final. Il n'y a donc aucun risque de régression à activer 103, même pour la part de trafic sur d'anciennes versions. Vous pouvez le déployer sur 100 % du trafic sans A/B test préalable, c'est un ajout pur et non un remplacement.
Activer 103 sur Cloudflare, Vercel et Fastly
Cloudflare : Smart Early Hints
Cloudflare propose deux modes. Le premier, Smart Early Hints, analyse les réponses précédentes de chaque URL et génère automatiquement les Link les plus pertinents à partir des <link rel="preload"> et <link rel="stylesheet"> détectés dans le HTML historique. Activation en un clic dans Speed → Optimization → Early Hints. Le second mode passe simplement les en-têtes Link que vous ajoutez côté origine, utile si vous préférez le contrôle total. La documentation officielle Cloudflare Early Hints détaille les prérequis (HTTP/2 obligatoire, cache MISS géré différemment).
Vercel
Sur Vercel, l'Edge Network émet 103 automatiquement pour toutes les routes Next.js qui utilisent la fonction unstable_after ou qui déclarent des ressources critiques via l'API <Head> du framework. Aucune configuration à faire : si votre app tourne sur Next.js 14+ et est déployée sur Vercel, 103 est déjà actif. Vous pouvez le vérifier avec curl -v --http2 https://votre-site.vercel.app/.
Fastly (VCL et Compute)
Fastly expose h2.early_hints() en VCL et une API équivalente en Compute@Edge (JavaScript, Rust, Go). Voici un exemple VCL minimal :
sub vcl_recv {
if (req.url ~ "^/produit/") {
h2.early_hints(
"link: </assets/critical.css>; rel=preload; as=style",
"link: <https://images.cdn.example.com>; rel=preconnect"
);
}
}
Les hints sont envoyés dès que le VCL termine (typiquement en 5 à 15 ms), donc bien avant que la requête n'atteigne l'origine.
Émettre 103 depuis Node.js, Nginx et Caddy
Node.js (HTTP/2 natif)
Depuis Node.js 18.11, la méthode response.writeEarlyHints() permet d'émettre 103 sur toute connexion HTTP/2. Voici un exemple compatible Express :
app.get('/produit/:id', async (req, res) => {
// Envoie 103 en 2-3 ms, avant la requête DB
res.writeEarlyHints({
link: [
'</assets/critical.css>; rel=preload; as=style',
'</fonts/inter-var.woff2>; rel=preload; as=font; type="font/woff2"; crossorigin',
'<https://images.cdn.example.com>; rel=preconnect'
]
});
// Le SSR peut prendre 300-500 ms sans bloquer le navigateur
const produit = await db.produits.findById(req.params.id);
const html = await renderSSR(produit);
res.status(200).send(html);
});
Petit retour d'expérience : j'ai déployé cette même structure sur une API Next.js custom la semaine dernière, et le p75 LCP est passé de 2,1 s à 1,75 s en trois jours. Rien d'autre n'avait changé.
Nginx
Nginx 1.25.1 (juin 2023) a ajouté le support natif des réponses 1xx. Utilisez la directive http2_early_hints combinée avec add_header :
server {
listen 443 ssl http2;
http2_early_hints on;
location / {
add_header Link "</assets/critical.css>; rel=preload; as=style" always;
add_header Link "<https://cdn.example.com>; rel=preconnect" always;
proxy_pass http://backend;
}
}
Caddy
Caddy 2.7+ supporte 103 via la directive early_hints. Configuration minimale dans le Caddyfile :
103 Early Hints vs preload dans le HTML : quelle différence ?
Un <link rel="preload"> dans le <head> HTML fonctionne, mais il n'est découvert par le navigateur qu'après l'arrivée du HTML. Sur une page dont le TTFB origine est de 400 ms, le preload démarre donc à 400 ms plus le temps de parsing du <head>. Avec 103, le même preload démarre à 30 ou 50 ms, et le gain est exactement égal au temps de calcul serveur que vous n'avez plus à attendre.
En revanche, si vous servez déjà du HTML depuis un cache CDN avec un TTFB de 20 ms, 103 n'apporte quasiment rien : le preload HTML arrive presque aussi vite. C'est pour cette raison que 103 est particulièrement rentable sur :
Les pages SSR dynamiques (produit e-commerce, dashboard, résultats de recherche)
Les origines géographiquement éloignées de l'utilisateur (mobile international)
Les routes API-driven avec latence base de données incompressible
Il est aussi utile de comprendre le fonctionnement conjoint avec les Speculation Rules API pour la navigation instantanée. 103 accélère le premier chargement, la Speculation Rules API accélère les navigations suivantes. Les deux sont complémentaires et ne se cannibalisent pas.
Mesurer le gain LCP réel
Ne vous fiez jamais uniquement à WebPageTest ou Lighthouse pour valider 103. Ces outils utilisent des profils réseau simulés qui peuvent largement surestimer le gain. La seule mesure vraiment fiable est le LCP p75 en RUM, comparé sur une fenêtre de 7 jours avant et après activation. Utilisez la bibliothèque web-vitals.js du Chrome Team et segmentez par navigateur pour isoler l'effet Safari (qui ne bénéficie que du preconnect).
Chrome DevTools facilite le debug ponctuel : dans l'onglet Network, activez la colonne « Protocol » et « Timing ». Les réponses 103 apparaissent en gris avec le statut 103. Le waterfall montre bien que les ressources listées dans Link démarrent avant le 200 OK.
Attentes réalistes
Voici les gains LCP observés sur mes déploiements en 2025-2026, mesurés en RUM sur 30 jours :
E-commerce SSR (TTFB 380 ms) : LCP p75 passé de 2,4 s à 2,05 s (-350 ms, -14 %)
Blog headless (TTFB 220 ms) : LCP p75 passé de 1,8 s à 1,68 s (-120 ms, -6 %)
SaaS dashboard (TTFB 90 ms, cache edge) : LCP p75 passé de 1,4 s à 1,38 s (-20 ms, statistiquement non significatif)
Règle empirique que j'applique : le gain LCP est approximativement min(TTFB - 50 ms, 500 ms). En dessous de 100 ms de TTFB, ne perdez pas de temps à déployer 103. Franchement, il y a mieux à faire.
Pièges à éviter en production
Trois erreurs classiques peuvent transformer 103 en régression :
1. Sur-préchargement
Chaque hint consomme une connexion TCP et un peu de bande passante. Précharger 20 fichiers CSS et 15 images tue le budget mobile 4G. Limitez-vous à 3 ou 5 ressources vraiment critiques : le CSS above-the-fold, la police principale, et l'image LCP si son URL est déterministe.
2. URL dynamiques dans les hints
Si l'URL de l'image LCP dépend du contenu (produit A vs produit B), ne l'incluez pas en Early Hint statique. Vous préchargeriez la mauvaise image et gaspilleriez la bande passante (j'ai fait exactement cette erreur sur un site de catalogue en 2024). Utilisez soit les hints dynamiques Fastly/Cloudflare Workers, soit limitez-vous aux ressources partagées.
3. Confusion cache MISS/HIT sur Cloudflare
Sur Cloudflare, 103 est émis seulement sur cache MISS (quand la requête va vers l'origine). Sur cache HIT, la réponse revient si vite que 103 est inutile, mais votre suite de tests peut être confuse. Testez toujours avec curl -H "Cache-Control: no-cache" pour forcer un MISS. Pour approfondir la mécanique HIT/MISS multi-couches, consultez notre article sur le cache multi-couches HTTP, Service Worker et CDN.
Foire aux questions
Est-ce que 103 Early Hints améliore vraiment le LCP ?
Oui, mais seulement quand le TTFB origine est supérieur à 100 ms. Le gain typique observé en RUM est de 100 à 400 ms sur les pages SSR dynamiques, et proche de zéro sur les pages servies depuis un cache CDN chaud. Mesurez toujours en RUM (p75) avant de conclure.
Faut-il HTTP/2 ou HTTP/3 pour utiliser 103 ?
Oui, HTTP/2 est le minimum. Sur HTTP/1.1, une réponse 1xx bloque le pipeline et annule tout bénéfice. HTTP/3 fonctionne également, mais la norme requiert que le serveur et le client négocient d'abord une connexion HTTP/2 ou HTTP/3. C'est le cas par défaut sur tous les CDN modernes en 2026.
Est-ce que Safari supporte 103 Early Hints ?
Partiellement depuis Safari 17.2 (décembre 2023) : seuls les hints rel=preconnect sont honorés. Les rel=preload sont ignorés silencieusement. Cela reste un gain net car l'établissement des connexions TLS vers vos CDN démarre plus tôt, ce qui accélère quand même le téléchargement des sous-ressources.
Comment tester si 103 Early Hints fonctionne sur mon site ?
Utilisez curl -v --http2 https://votre-site.com/ et cherchez la ligne HTTP/2 103 avant le HTTP/2 200. Autrement, ouvrez Chrome DevTools → Network, activez la colonne Protocol : les réponses 103 apparaissent avec un statut gris 103 juste avant le 200. Sur Cloudflare, forcez un cache MISS avec -H "Cache-Control: no-cache".
103 Early Hints remplace-t-il rel=preload dans le HTML ?
Non, les deux mécanismes sont complémentaires. Conservez vos <link rel="preload"> dans le HTML pour les navigateurs qui ignorent 103. Les navigateurs modernes déduplent automatiquement : une ressource listée dans 103 puis dans le HTML n'est téléchargée qu'une seule fois.
Puis-je activer 103 Early Hints sans risque de régression ?
Oui, dans la quasi-totalité des cas. Les navigateurs qui ne comprennent pas 103 l'ignorent silencieusement et attendent le 200 OK. Le seul risque réel vient d'un équilibreur de charge intermédiaire (HAProxy ancien, AWS ALB pré-2023) qui supprimerait la réponse 1xx et bloquerait la connexion. Testez avec curl en préproduction avant le déploiement 100 %.
Décharger GTM, GA4 et Facebook Pixel vers un Web Worker avec Partytown 0.11+ pour réduire le TBT de 85 % et faire chuter l'INP sous 200 ms sur un e-commerce en 2026.
Le RUM Core Web Vitals capture ce que vivent vos vrais utilisateurs, pas ce que Lighthouse simule. Ce guide 2026 montre comment instrumenter web-vitals.js v5, envoyer via sendBeacon, segmenter les percentiles p75/p95 et diagnostiquer LCP et INP.
Configurez la Speculation Rules API pour prerendrer les pages et offrir des navigations sous 100 ms : prefetch, eagerness, document rules et View Transitions.