Desempenho no Next.js
Regras
- Imagens: sempre
next/image com sizes explícitos, priority apenas para herói LCP. Fontes: next/font (sem <link> do Google bloqueante de renderização).
- Meça primeiro:
@next/bundle-analyzer, saída do next build, Lighthouse. Corrija o maior gargalo primeiro.
dynamic(() => import(...), { ssr: false }) para widgets pesados apenas no cliente (gráficos, editores). Mantenha o JS inicial < 200KB gz sempre que possível.
- Faça cache agressivo: estático +
revalidate (ISR) para páginas semidinâmicas; use loading.tsx/Suspense para transmitir partes lentas em vez de bloquear o TTFB.
- Evite cascatas: paralelize em RSC, memorize
fetch repetitivo (auto-deduplicado por requisição), use unstable_cache para operações computacionais caras.
Padrões
import Image from 'next/image';
<Image src="/hero.jpg" alt="Dashboard" width={1200} height={630} priority sizes="100vw" />
<Image src="/avatar.png" alt="Usuário" 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="en" className={inter.className}><body>{children}</body></html>;
}
import dynamic from 'next/dynamic';
const Chart = dynamic(() => import('@/components/chart'), { ssr: false, loading: () => <p>Carregando gráfico…</p> });
export const revalidate = 60;
const withBundleAnalyzer = require('@next/bundle-analyzer')({ enabled: process.env.ANALYZE === 'true' });
module.exports = withBundleAnalyzer({});
Lista de Verificação