Comment auditer les Core Web Vitals d'un site Next.js
Les Core Web Vitals (LCP, INP, CLS) sont devenus un facteur de ranking SEO et un indicateur direct de taux de conversion. Sur une stack Next.js déployée sur Vercel, l'architecture (SSR, ISR, App Router, streaming) introduit des comportements de performance spécifiques qu'un audit générique ne détecte pas toujours. Voici une méthodologie concrète pour identifier et corriger les problèmes.
Distinguer données de laboratoire et données de terrain
Ne jamais auditer uniquement avec Lighthouse en local — les résultats varient de 30 à 40% selon le CPU throttling et le réseau simulé, sans refléter l'expérience réelle des utilisateurs.
Données de terrain (field data) : utilisez le CrUX Dashboard (Chrome UX Report) via BigQuery ou l'API CrUX pour obtenir les percentiles réels (p75) par URL. Vercel Analytics expose également ces métriques nativement si le site y est déployé, avec segmentation par device et région.
Données de laboratoire (lab data) : Lighthouse CI intégré en pipeline permet de tester chaque PR avant merge, avec des seuils de non-régression :
{
"ci": {
"assert": {
"assertions": {
"largest-contentful-paint": ["error", { "maxNumericValue": 2500 }],
"cumulative-layout-shift": ["error", { "maxNumericValue": 0.1 }],
"interaction-to-next-paint": ["error", { "maxNumericValue": 200 }]
}
}
}
}
Le croisement des deux est indispensable : un bon score Lighthouse local avec un mauvais p75 CrUX signale souvent un problème réseau (CDN mal configuré, TTFB élevé sur certaines régions) invisible en local.
Diagnostiquer le LCP sur une architecture Next.js
Le LCP dépend rarement du framework lui-même, mais de la manière dont les ressources critiques sont chargées :
- Images non optimisées via
next/image: vérifiez que l'attributpriorityest bien posé sur l'image LCP (hero, above-the-fold). Sans lui,next/imageappliqueloading="lazy"par défaut, ce qui retarde le chargement de l'élément le plus critique. - Fonts bloquantes : utilisez
next/font(Google ou local) plutôt qu'un<link>externe. Il élimine le FOIT/FOUT et précharge automatiquement les fichiers WOFF2 avec les bonsfont-display. - TTFB côté SSR : sur l'App Router, une donnée fetchée sans cache (
fetch(url, { cache: 'no-store' })) dans un Server Component bloque le rendu initial. Auditez leswaterfallréseau dans l'onglet Network de Chrome DevTools pour repérer les requêtes séquentielles qui devraient être parallélisées avecPromise.all.
Traquer le CLS généré par le rendu hybride
Le CLS est souvent sous-estimé car il n'apparaît qu'après hydratation :
- Composants chargés dynamiquement (
next/dynamic) sans dimension réservée provoquent un shift au moment du swap. Réservez systématiquement l'espace avecmin-heightou un skeleton de taille identique. - Publicités et widgets tiers (chat, consent banner) injectés côté client sans
aspect-ratiodéfini. Isolez-les dans un conteneur à hauteur fixe. - Web fonts avec fallback mal calibré : utilisez
size-adjustdans la confignext/fontpour aligner la métrique du fallback système sur la police finale, évitant le reflow au swap.
L'outil web-vitals en mode debug (reportAllChanges: true) permet de logger chaque shift avec l'élément DOM concerné, directement en production via un endpoint de collecte custom.
Adresser l'INP : le successeur du FID
Depuis mars 2024, l'INP remplace le FID. Sur Next.js, les points de friction typiques :
- Hydratation lourde : un Client Component volumineux avec beaucoup de state (
useState,useEffecten cascade) bloque le thread principal. Découpez en Server Components partout où l'interactivité n'est pas nécessaire — c'est l'intérêt premier de l'App Router. - Third-party scripts non différés : chargez les scripts analytics/marketing via `next/
Le Template Puppeteer B2B, gratuit
Un script d'automatisation prêt à l'emploi pour vos scrapers et générateurs de PDF B2B. Envoyé par e-mail, sans spam.
Partenaire
Hébergez vos APIs sur une infrastructure rapide
Hostinger propose un hébergement cloud et VPS haute performance avec NVMe, CDN intégré et déploiement Git — idéal pour vos back-ends et APIs JSON.