Performances Next.js
Règles
- Images : toujours utiliser
next/image avec des sizes explicites, priority uniquement pour l'image héro LCP. Polices : next/font (pas de balise <link> Google bloquant le rendu).
- Mesurer d'abord :
@next/bundle-analyzer, la sortie de next build, Lighthouse. Corriger le plus gros goulot d'étranglement en premier.
dynamic(() => import(...), { ssr: false }) pour les widgets lourds côté client uniquement (graphiques, éditeurs). Garder le JS initial sous 200 Ko gz si possible.
- Mettre en cache agressivement : pages statiques +
revalidate (ISR) pour les pages semi-dynamiques ; loading.tsx/Suspense pour diffuser les parties lentes sans bloquer le TTFB.
- Éviter les cascades : paralléliser dans RSC, mémoïser les appels
fetch répétés (déduplication automatique par requête), utiliser unstable_cache pour les calculs coûteux.
Modèles
import Image from 'next/image';
<Image src="/hero.jpg" alt="Tableau de bord" width={1200} height={630} priority sizes="100vw" />
<Image src="/avatar.png" alt="Utilisateur" width={64} height={64} sizes="64px" />
import { Inter } from 'next/font/google';
const inter = Inter({ subsets: ['latin'], display: 'swap' });
export default function RootLayout({ children }: { children: React.ReactNode }) {
return <html lang="fr" className={inter.className}><body>{children}</body></html>;
}
import dynamic from 'next/dynamic';
const Chart = dynamic(() => import('@/components/chart'), { ssr: false, loading: () => <p>Chargement du graphique…</p> });
export const revalidate = 60;
const withBundleAnalyzer = require('@next/bundle-analyzer')({ enabled: process.env.ANALYZE === 'true' });
module.exports = withBundleAnalyzer({});
Liste de vérification