- Next.js
- Performance
- SEO
- Web
LCP, CLS, INP. Les trois métriques, ce qui les dégrade concrètement sur l'App Router, et l'ordre dans lequel s'y attaquer — en commençant par la seule mesure qui compte.
Les Core Web Vitals sont trois mesures de l'expérience réelle : la vitesse d'affichage du contenu principal (LCP), la stabilité visuelle (CLS) et la réactivité aux interactions (INP). Elles pèsent sur le référencement, mais surtout sur la conversion — un formulaire qui saute sous le doigt au moment du clic ne se rattrape pas.
D'abord : mesurer la bonne chose
L'erreur la plus commune est d'optimiser contre Lighthouse en local. Lighthouse produit des données de laboratoire : une machine puissante, un réseau simulé, une page froide. Google évalue votre site sur des données de terrain — vos visiteurs réels, leurs téléphones réels, leurs réseaux réels.
Les deux divergent systématiquement, et dans le même sens. Une page à 98 en local peut échouer sur le terrain, généralement à cause de l'INP, que Lighthouse ne mesure pas — il n'y a personne pour cliquer.
Conséquence pratique : Lighthouse sert à trouver la cause d'un problème, jamais à décider qu'il n'y en a pas. La décision se prend sur les données de terrain.
LCP — presque toujours une image, et presque toujours la même erreur
Sur un site vitrine, l'élément LCP est le visuel de la première section dans neuf cas sur dix. Trois causes reviennent, par ordre de fréquence.
L'image n'est pas prioritaire. Par défaut, next/image charge en différé — un excellent comportement pour tout ce qui est plus bas dans la page, et exactement le mauvais pour l'image LCP, qu'il retarde d'un cycle complet.
<Image src={cover} alt="" fill priority sizes="(max-width: 768px) 100vw, 50vw" />L'attribut sizes est absent ou faux. Sans lui, le navigateur suppose la largeur de la fenêtre et télécharge une variante bien plus lourde que nécessaire. Sur mobile, l'écart se compte en centaines de kilo-octets — c'est-à-dire en secondes.
Le composant est un composant client sans raison. Un "use client" posé haut dans l'arbre entraîne toute sa descendance dans le bundle navigateur. Le contenu n'apparaît alors qu'après le téléchargement et l'exécution du JavaScript, alors que le serveur aurait pu l'envoyer déjà rendu.
La règle de l'App Router mérite d'être rappelée : serveur par défaut, client à la demande. Et la frontière se pose au plus bas — sur le bouton interactif, pas sur la section qui le contient.
CLS — la police et les emplacements non réservés
Deux causes dominent, et les deux se règlent une fois pour toutes.
Les polices. next/font résout l'essentiel automatiquement : il héberge la police, supprime la requête vers un domaine tiers et calcule une police de repli aux métriques ajustées, ce qui évite le décalage au moment de la substitution.
const nunito = Nunito({ subsets: ["latin"], display: "swap", variable: "--font-nunito" });Tout ce qui apparaît après coup : bannière de consentement, encart d'annonce, contenu chargé par une requête, image sans dimensions. Chacun pousse le contenu vers le bas. La parade est toujours la même — réserver l'espace avant de le remplir, avec un rapport d'aspect ou une hauteur minimale.
Cas particulier fréquent : le bandeau de consentement aux cookies. Superposé, il ne coûte rien ; inséré dans le flux, il décale toute la page à chaque visite.
INP — la métrique qu'on découvre en production
L'INP mesure le délai entre une interaction et le retour visuel correspondant. C'est la métrique la plus souvent en échec, et la plus invisible en développement : sur une machine de développeur, tout est instantané.
Trois causes, par ordre d'impact réel :
- Trop de JavaScript sur le fil principal. Une bibliothèque de 300 ko chargée pour une seule animation bloque tout ce qui suit. La question à se poser n'est pas « est-ce lent ? » mais « est-ce nécessaire ? ».
- Des rendus en cascade. Un état posé trop haut dans l'arbre fait rerendre une section entière à chaque frappe dans un champ de saisie.
- Du travail synchrone dans le gestionnaire d'événement. Un tri, un filtre ou un calcul lancé au clic retarde le retour visuel. Afficher d'abord, calculer ensuite.
L'ordre dans lequel s'y prendre
Par rendement décroissant, à partir des données de terrain :
- Identifier l'élément LCP réel sur la page la plus visitée. Souvent, une seule propriété
prioritysuffit. - Faire descendre la frontière client le plus bas possible dans l'arbre.
- Réserver l'espace de tout ce qui arrive après le premier rendu.
- Auditer le poids du JavaScript route par route — et supprimer avant d'optimiser.
Un point mérite d'être dit clairement : la plupart des gains viennent des trois premières étapes, et aucune ne demande de refonte. Les projets qui échouent sur ces métriques ont rarement un problème d'architecture ; ils ont une image non prioritaire et un "use client" mal placé.