Optimiser les performances d'une application Next.js moderne
Pourquoi la performance est une fonctionnalité
Sur le web moderne, chaque centaine de millisecondes compte : un Largest Contentful Paint (LCP) lent dégrade le SEO, augmente le taux de rebond et fait chuter la conversion. Next.js fournit les outils pour aller vite par défaut, à condition de respecter quelques principes d'architecture.
1. Server Components par défaut, Client Components par exception
Depuis l'App Router, les composants sont des Server Components par défaut : leur code ne part jamais vers le navigateur. Réservez la directive "use client" aux seules zones interactives (formulaires, menus, animations au clic, drag & drop).
Règles pratiques : - Récupérez les données côté serveur : fetch dans un Server Component, puis passez le résultat en props aux composants clients. - Remontez "use client" le plus bas possible : une page entière ne doit jamais devenir cliente à cause d'un seul bouton. - Déportez la logique lourde (formatage, parsing markdown, calculs) côté serveur pour réduire le bundle client.
2. Des images qui ne plombent pas le LCP
Les images sont la première cause de LCP lent. Le composant next/image apporte le redimensionnement automatique, les formats modernes (AVIF/WebP) et le lazy loading intégré.
- Déclarez width/height ou fill + sizes pour éviter les sauts de mise en page (CLS).
- Ajoutez priority uniquement à l'image hero : tout marquer prioritaire annule le bénéfice.
- Servez la bonne taille : inutile d'envoyer 2400 px à un écran mobile de 390 px.
3. Des polices rapides avec next/font
Les polices chargées via un lien CSS externe bloquent le rendu et provoquent des décalages de mise en page. next/font les auto-héberge et les optimise dès le build.
- Chargez uniquement les subsets nécessaires (latin) et les graisses réellement utilisées.
- Gardez display: swap pour afficher le texte immédiatement avec une police de secours.
- Préférez une police variable plutôt que six fichiers statiques quand c'est possible.
4. Un bundle JavaScript sous contrôle
Chaque kilo de JavaScript client retarde l'interactivité (INP). Surveillez le bundle comme un budget de dépenses.
- Fractionnez avec next/dynamic : éditeurs riches, graphiques et modales lourdes ne doivent se charger qu'à l'usage.
- Analysez avec @next/bundle-analyzer pour repérer les dépendances qui gonflent le bundle.
- Évitez les dépendances redondantes : une fonction utilitaire de vingt lignes ne justifie pas 40 Ko de librairie.
5. Rendu et cache : statique d'abord, dynamique si besoin
- Préférez le statique pour le contenu public, avec revalidate pour rafraîchir en arrière-plan (ISR).
- Isolez le dynamique : un bandeau personnalisé ne doit pas forcer toute la page en rendu dynamique ; utilisez Suspense pour diffuser les zones lentes au fil de l'eau.
- Mettez en cache les fetch serveur et dédupliquez les requêtes identiques au sein d'une même page.
Mesurer avant d'optimiser
Sans mesure, l'optimisation est du hasard. Visez un LCP inférieur à 2,5 s, un INP inférieur à 200 ms et un CLS inférieur à 0,1 sur mobile : testez avec Lighthouse en mode mobile bridé, surveillez les Core Web Vitals réelles et rejouez les mesures après chaque changement.
Conclusion
La performance avec Next.js tient à quatre réflexes : servir par défaut depuis le serveur, n'envoyer au client que l'interactivité nécessaire, optimiser images et polices, et mesurer en continu. Appliqués ensemble, ces leviers transforment une application lourde en expérience instantanée — c'est exactement la démarche que j'applique sur ce portfolio et sur mes projets clients.