Performance

Optimiser le LCP en Next.js : leviers par ordre d'impact

Ton LCP dépasse 2,5 s sur Lighthouse ? Voilà les leviers Next.js qui paient vraiment, classés par impact réel, avec seuils chiffrés.

Illustration editoriale d'une page web qui se construit en cascade, avec l'image hero en peche mise en avant comme element LCP prioritaire

Tu ouvres Lighthouse, tu vois LCP : 4,2 s en rouge, et tu te demandes si c'est grave. La réponse courte : oui, parce que c'est l'un des trois Core Web Vitals que Google regarde pour le classement. La réponse longue : il y a cinq ou six endroits à regarder, et ils n'ont pas tous le même poids. Voici lesquels, dans l'ordre d'impact réel sur un site Next.js.

Pourquoi le LCP coince spécifiquement sur Next.js

Le LCP (Largest Contentful Paint) mesure le temps qu'il faut pour que le plus gros élément visible de ta page apparaisse à l'écran. Sur une page d'accueil ou un article de blog Next.js, cet élément est presque toujours l'image hero ou un gros bloc de texte au-dessus du pli. Le seuil officiel à viser, défini par Google, est de 2,5 secondes mesurées sur le 75e centile des visites réelles. Au-dessus de 4 secondes, la page est classée "Poor" par Chrome, et ça commence à peser sur les conversions comme sur le SEO.

Le piège côté Next.js, c'est que par défaut le framework n'a aucun moyen de deviner quelle image tu considères comme prioritaire. Il applique du loading="lazy" à toutes les images, sauf si tu le dis. Résultat : l'image hero attend que le HTML et le JS soient parsés, puis attend son tour dans la file d'attente du navigateur, puis arrive enfin. Sur une connexion 4G moyenne, ça veut dire 3 à 5 secondes de LCP, alors que la même image marquée prioritaire descend à 1,2 s. C'est le premier réflexe à apprendre.

Levier 1 : marquer l'image hero comme prioritaire

Le levier le plus rentable, et de loin, c'est l'attribut priority sur le composant next/image correspondant à l'image hero. Concrètement, tu repères dans ta page l'image qui correspond au LCP (souvent visible dans le rapport Lighthouse, section "Largest Contentful Paint element"), et tu ajoutes priority à son JSX. Next.js va alors injecter un <link rel="preload"> dans le <head>, basculer le loading sur eager, et passer le fetchPriority à high. Sur les sites que je migre, ce seul changement fait gagner en moyenne 1,5 à 2 secondes de LCP, sans toucher au reste.

Schema waterfall avant / apres : l'image hero passe du bas au haut de la cascade de chargement

À retenir : priority ne se met que sur UNE image par page (celle au-dessus du pli, la plus grosse). Si tu en mets cinq, tu noies le signal, et le navigateur n'arbitre plus rien. Petit complément utile : sur les images hero responsives, soigne aussi l'attribut sizes. Un sizes="100vw" pour une image qui fait en réalité 800 px de large à l'écran, c'est trois fois trop de pixels téléchargés. Le bon réflexe : sizes="(min-width: 1024px) 800px, 100vw", et tu coupes la facture image en deux.

Levier 2 : faire travailler le serveur, pas le navigateur

Si ton site est en "use client" partout ou en client-side rendering pur, le navigateur reçoit un HTML quasi vide, télécharge le bundle JavaScript, l'exécute, puis seulement après commence à demander l'image hero. C'est précisément ce que Next.js cherche à éviter avec ses trois modes de rendu : SSG (génération au build), SSR (rendu serveur à la demande) et RSC (React Server Components, depuis le App Router). Passer une page client en page serveur ou statique réduit typiquement le LCP de 40 à 60 % sur les sites que j'audite, parce que le HTML arrive avec l'image hero déjà déclarée dans le code source, prête à être préchargée.

Concrètement, sur l'App Router (depuis Next.js 13), une page est server par défaut. Tu n'as rien à faire, sauf à ne pas la faire basculer en client par erreur. Le réflexe à éviter : mettre "use client" en haut du composant page.tsx parce qu'on a besoin d'un useState pour un menu. Le bon découpage, c'est de laisser la page en serveur et de pousser le "use client" dans le sous-composant qui en a vraiment besoin. C'est l'un des sujets que j'aborde en détail sur la page site rapide et durable.

Levier 3 : alléger le chemin critique CSS et fonts

Une fois l'image hero préchargée et le rendu serveur en place, le plafond suivant, c'est le CSS bloquant et les fonts qui retardent le premier paint. Next.js fait déjà beaucoup côté CSS : il inline les styles critiques de la page, splitte le CSS par route, et applique du tree-shaking via Tailwind ou les CSS modules. Le piège classique, c'est d'importer un gros pack d'icônes ou une librairie UI complète dans le layout racine. Tu te retrouves avec 60 ko de CSS qui bloquent le rendu, alors que la page en utilise 8.

Côté fonts, le bon réflexe est next/font. Le module charge la font en self-host (donc sans round-trip vers Google Fonts), génère un font-display: swap par défaut, et calcule un size-adjust pour limiter le décalage visuel quand la font web prend le relais. Si ta font hero est déclarée avec next/font/google dans le layout racine, elle est préchargée automatiquement, et tu évites le FOIT (Flash of Invisible Text) qui retarde le LCP quand l'élément texte est ton plus gros bloc. Plus loin, tu peux gagner encore 100 à 300 ms sur les fonts custom en passant la variante subset au strict nécessaire (latin uniquement si tu n'as pas de cyrillique).

Mesurer pour de vrai, pas seulement dans Lighthouse

Lighthouse, c'est bien pour itérer en local, mais ses scores sont une simulation sur une machine de référence, avec un throttling artificiel. Le LCP qui compte pour Google, c'est celui mesuré sur les vraies visites de ton site, agrégé dans le rapport CrUX (Chrome User Experience Report), visible dans Search Console et PageSpeed Insights. Sur un site PME avec peu de trafic, CrUX peut ne pas avoir assez de données pour publier un score. Dans ce cas, tu passes par du RUM (Real User Monitoring) : Vercel Analytics, Cloudflare Web Analytics ou un script web-vitals minimal qui envoie les métriques à ton endpoint.

Trio de jauges Core Web Vitals avec la jauge LCP plus grande a gauche que INP et CLS

Un point qui surprend souvent les clients : le LCP mobile et desktop sont mesurés séparément, et Google les agrège indépendamment dans le ranking. Tu peux très bien avoir 1,8 s en desktop (vert) et 3,9 s en mobile (rouge), et c'est le mobile qui pèsera sur ton positionnement pour la majorité du trafic. Si tu veux voir comment je traite ces sujets en production, regarde quelques projets du portfolio.

À lire ensuite

FAQ

Quel est un bon score LCP en 2026 ?

Le seuil "Good" reste fixé par Google à 2,5 secondes mesurées au 75e centile sur 28 jours glissants. Entre 2,5 et 4 s, c'est "Needs Improvement". Au-dessus de 4 s, c'est "Poor" et ça commence à peser sur ton classement. Vise sous 2 s en cible interne pour avoir une marge de sécurité quand le trafic réel grimpe.

Le LCP est-il vraiment un facteur de classement Google ?

Oui, depuis 2021 c'est l'un des trois Core Web Vitals officiellement intégrés à l'algorithme de classement. Concrètement, à contenu équivalent, la page avec un LCP sous 2,5 s passe devant celle qui est à 4 s. Et au-delà du SEO, l'impact sur les conversions est mesurable : Google a publié des études internes montrant 24 % de bounce rate en plus quand le LCP dépasse 4 s sur mobile.

Combien de temps pour passer de 4 s à 2 s sur un site Next.js existant ?

Sur un site relativement propre, une demi-journée à une journée de dev suffit : ajouter priority, soigner les sizes, vérifier que les pages sont bien serveur. Sur un site avec dette technique (gros bundles JS, fonts non optimisées, images non compressées), prévoir 2 à 3 jours, parce qu'il faut souvent refactorer le découpage client / serveur.

Pourquoi mon LCP est mauvais en mobile mais bon en desktop ?

Trois causes habituelles : (1) les images servies en mobile sont trop lourdes parce que tu n'as pas configuré sizes correctement, (2) la connexion 4G simulée est plus lente que ta fibre locale, (3) le CPU mobile parse le JavaScript deux à trois fois plus lentement qu'un desktop, ce qui retarde le hydratation et donc le rendu de l'image hero dans certains cas. C'est aussi le sujet du volet GEO et SEO mobile que je traite côté apparaître sur Google et sur les IA.

Sources