Éléments essentiels du Web : l'économie de la milliseconde
Google vous classe en fonction de l'expérience utilisateur. Une plongée technique approfondie dans LCP (Chargement), CLS (Stabilité) et INP (Interaction).
Google classait les sites Web en fonction de mots-clés et de backlinks. En 2021, ils ont introduit la Page Experience Update. Ils ont modifié l’algorithme pour filtrer les sites « ennuyeux ».
- Gênant = Lent (LCP).
- Ennuyeux = Jumpy (CLS).
- Ennuyeux = Ne répond pas (INP).
Si vous échouez à ces Core Web Vitals (CWV), vous ne vous contentez pas d’ennuyer les utilisateurs ; vous perdez du trafic organique. Chez Maison Code Paris, nous traitons la Performance comme une Caractéristique. Un site de luxe lent est une contradiction dans les termes.
Pourquoi Maison Code en parle
Chez Maison Code Paris, nous agissons comme la conscience architecturale de nos clients. Nous héritons souvent de stacks “modernes” construites sans compréhension fondamentale de l’échelle.
Nous abordons ce sujet car il représente un point de pivot critique dans la maturité de l’ingénierie. Une mise en œuvre correcte différencie un MVP fragile d’une plateforme résiliente de niveau entreprise.
1. Largest Contentful Paint (LCP) : le délai de 2,5 secondes
LCP mesure les performances de chargement. Il arrête l’horloge lorsque le plus grand élément visible (généralement l’image du héros ou le texte de blocage H1) est rendu. Cible : < 2,5 secondes.
La physique du LCP
LCP est une course contre quatre sous-parties :
- TTFB (Time to First Byte) : Temps de réponse du serveur.
- Délai de chargement des ressources : délai jusqu’à ce que le navigateur découvre l’URL de l’image.
- Temps de chargement des ressources : Il est temps de télécharger l’image.
- Délai de rendu des éléments : temps nécessaire pour peindre les pixels.
Comment y remédier (Stratégie Next.js)
1. Ne chargez pas le héros paresseusement
Les développeurs adorent « loading=“lazy” ». Mais si vous le placez sur l’image Hero, le navigateur attend d’analyser la balise <img> pour commencer le téléchargement.
Vous devez Eager Load le candidat LCP.
// Mauvais
<Image src="/hero.jpg" chargement="lazy" />
// Bien (Suivant.js)
<Image src="/hero.jpg" priorité={true} />
2. Précharger les ressources critiques
Dites au navigateur dans le <head> : “Vous aurez besoin de cette police et de cette image immédiatement.”
<link rel="preload" href="/hero.webp" as="image" />
<link rel="preload" href="/fonts/inter.woff2" as="font" crossorigin />
3. Utiliser le format AVIF WebP est bon. AVIF est meilleur (20% plus petit). Assurez-vous que votre CDN prend en charge la négociation de contenu.
2. Cumulative Layout Shift (CLS) : l’indice de stabilité
CLS mesure la stabilité visuelle. Il calcule la quantité de contenu déplacée de manière inattendue. Cible : < 0,1.
Scénario : l’utilisateur essaie de cliquer sur “Commander”. Une annonce se charge au-dessus du bouton. Le contenu pousse vers le bas. L’utilisateur clique sur “Annuler” à la place. Il s’agit d’un motif sombre, même s’il est accidentel.
Le problème : les proportions
Si vous incluez une image sans dimensions :
<img src="photo.jpg" />
Le navigateur ne connaît pas la hauteur jusqu’au téléchargement de l’image. Il restitue une hauteur de 0 px, puis passe à 500 px.
Correction : réservez toujours de l’espace.
CSS aspect-ratio est votre ami.
.hero-wrapper {
rapport hauteur/largeur : 16 / 9 ;
arrière-plan : #f0f0f0 ; /* Couleur de l'espace réservé */
}
Le changement de police (FOIT/FOUT)
Les polices personnalisées prennent du temps à charger. Si le navigateur masque le texte jusqu’au chargement de la police (FOIT), vous obtenez un flash. Si le navigateur affiche la police de secours (Arial) puis permute (Inter), la largeur change. Les sauts de ligne changent. Changements de disposition.
Correction : utilisez « font-display : facultatif » ou faites correspondre les métriques.
Nous utilisons @next/font qui aligne automatiquement les métriques de police de secours pour éviter tout changement de mise en page.
3. Le coût des polices lourdes
Les designers adorent les polices. Les ingénieurs les craignent. Un seul poids de Circular Std est de 30 Ko (WOFF2). Si vous chargez Regular, Bold, Italic, Black -> 120KB. Cela bloque le rendu du texte (FOIT). Stratégie :
- Sous-ensemble : vous n’avez pas besoin de caractères grecs/cyrilliques. Sous-ensemble de Latin-1. (Économise 50%).
- Polices variables : utilisez un fichier (
Inter-Variable.woff2) qui contient tous les poids. Il gère mieux l’animation. - Auto-hôte : éliminez la poignée de main TLS vers
fonts.googleapis.com.
4. Différer les CSS non critiques
Tailwind est génial car il est petit (10 Ko).
Mais les anciens projets Sass ont souvent « main.css » (500 Ko).
Le navigateur arrête le rendu jusqu’à ce que « main.css » soit téléchargé.
Correction : extrayez le “CSS critique” (styles pour l’en-tête/le héros) et insérez-le dans <head>.
Chargez le reste de manière asynchrone :
<link rel="stylesheet" href="main.css" media="print" onload="this.media='all'">
Cette astuce augmente le LCP d’environ 1 seconde sur les réseaux 3G.
5. Interaction avec Next Paint (INP) : la réactivité
Remarque : INP a remplacé le FID (First Input Delay) en mars 2024.
INP mesure la Latence des événements. “Lorsque je clique sur le bouton Menu, combien de millisecondes s’écoulent avant que le menu ne s’ouvre réellement ?” Cible : < 200 millisecondes.
Le coupable est presque toujours Le fil principal. JavaScript est monothread. Si le navigateur est en train d’analyser un énorme paquet d’hydratation de 5 Mo et que vous cliquez sur « Menu », le navigateur dit : « Attendez, je suis occupé ». L’interface utilisateur se fige.
Stratégies pour corriger l’INP
1. Céder au fil principal Divisez les tâches longues. Si vous itérez plus de 10 000 éléments, faites-le par morceaux.
// Blocage
items.forEach(processus);
// Non bloquant (cédant)
fonction asynchrone processAsync() {
pour (const élément d'éléments) {
wait planificateur.postTask(() => process(item));
}
}
2. Réagir à useTransition Dans React 18, utilisez « useTransition » pour marquer les mises à jour comme non urgentes. Cela indique à React : “Si l’utilisateur clique, interrompez ce travail de rendu pour gérer le clic.”
const [isPending, startTransition] = useTransition();
fonction selectTab(nextTab) {
startTransition(() => {
setTab(prochainTab);
});
}
4. Mesure : données de terrain vs données de laboratoire
Les développeurs vivent dans Lab Data (Lighthouse sur un MacBook rapide). Google réside dans Field Data (CrUX - Chrome User Experience Report). CrUX collecte des données réelles auprès d’utilisateurs réels (souvent sur des téléphones Android lents).
Votre score Lighthouse pourrait être de 100. Mais si votre utilisateur P75 (75e centile) a une connexion lente, votre score CrUX peut être « médiocre ». Toujours optimiser pour l’utilisateur P75 sur 4G.
5. Impact sur les tiers
Qui tue vos Web Vitals ? Habituellement :
- Widgets de chat (Interphone/Drift) : d’énormes bundles.
- Pixels de suivi : blocage du fil principal.
- Outils de test A/B (optimisés) : masquer le contenu du corps pour une expérience « sans scintillement » (tue LCP).
Solution : déplacez-les vers Web Workers à l’aide de Partytown. (Voir Taille du bundle).
6. L’API des règles de spéculation (prérendu)
C’est l’option nucléaire pour la vitesse. Vous pouvez demander à Chrome de afficher la page suivante en arrière-plan avant que l’utilisateur ne clique. Pas seulement télécharger le HTML. Exécutez le JS et peignez les pixels. Lorsqu’ils cliquent, la transition est de 0 ms. Instantané.
{
"pré-rendu": [
{
"source": "liste",
"urls": ["/page suivante", "/cart"]
}
]
}
Nous l’utilisons pour le flux « Ajouter au panier » -> « Commander ». Cela ressemble à une application native.
7. Navigations douces et CWV
Dans une application à page unique (Next.js), la navigation de l’accueil à la page produit est une navigation douce. Auparavant, Core Web Vitals les ignorait fortement. En 2024, Google a mis à jour les métriques pour suivre « INP sur les navigations douces ». Si votre transition JS prend 500 ms pour récupérer JSON et afficher la nouvelle page, vous échouez LCP/INP. Correction : utilisez l’interface utilisateur optimiste. Montrez immédiatement un squelette. N’attendez pas la fin de « wait fetch() » avant de modifier l’URL.
9. Surveillance des utilisateurs réels (RUM)
Lighthouse est un « test de laboratoire ». Il fonctionne dans un environnement propre. Les vrais utilisateurs exécutent Spotify en arrière-plan et 50 onglets ouverts. Vous avez besoin de RUM. Nous utilisons Vercel Analytics (ou SpeedCurve). Il suit les données vitales des visiteurs réels. Si votre LCP est de 1,2 s sur iPhone 15 mais de 4,5 s sur iPhone 11, RUM vous le dit. Les données du laboratoire mentent. Les données de terrain détectent les fuites de revenus.
10. Pourquoi Maison Code ?
Chez Maison Code, nous sommes des extrémistes de la performance. Nous ne nous contentons pas de « minifier le CSS ». Nous concevons Zero-Layout-Shift et Instant-Interaction. Nous savons que pour les marques de luxe, « Slow » = « Cheap ». Nous auditons l’ensemble de votre stack, du Edge CDN au React Hydration. Nous proposons des sites qui semblent natifs, même sur les réseaux 4G du tiers monde. Parce que 100 ms de latence = 1% de baisse de revenus (étude Amazon).
12. La différence entre TBT et INP
Le temps de blocage total (TBT) est une métrique de laboratoire. L’interaction avec Next Paint (INP) est une métrique de champ. TBT prédit INP. Si votre TBT est élevé (> 200 ms), votre INP sera probablement faible. Boucle d’optimisation :
- Exécutez Lighthouse (mesurez le TBT).
- Optimiser l’hydratation.
- Déployez.
- Attendez 28 jours pour les données CrUX (mesure INP).
- Répétez. N’attendez pas 28 jours pour savoir si vous l’avez réparé. Utilisez TBT comme proxy.
13. Conclusion
Les Core Web Vitals ne sont pas que des mesures. Ce sont des mandataires pour le respect. Respecter le temps de votre utilisateur. Respecter la batterie de leur appareil. Google impose simplement les bonnes manières. Si vous traitez bien l’utilisateur, Google vous traite bien.
Votre site est-il lent ?
Votre Search Console affiche-t-elle des « URL médiocres » ? Nous effectuons des audits de performance approfondis pour résoudre l’enfer de l’hydratation. Engagez nos Architectes.