Como eu penso performance em Next.js
Estratégias práticas para otimizar aplicações Next.js e alcançar Core Web Vitals perfeitos.
Performance na web não é apenas sobre "fazer o site carregar rápido". É sobre experiência do usuário, conversão e, em última análise, receita. Quando trabalhamos com Next.js, temos um framework poderoso em mãos, mas é fácil cair em armadilhas que degradam a performance se não prestarmos atenção aos detalhes certos.
O mindset de performance
Muitos desenvolvedores deixam a performance para o final. "Primeiro faz funcionar, depois otimiza". Embora a otimização prematura seja um problema, a negligência com performance arquitetural é pior. Performance deve ser uma feature, não um fix.
1. Imagens são o vilão número 1
O componente next/image é fantástico, mas ele não faz milagres se você não o usar corretamente.
- Use
sizessempre: O erro mais comum é não definir o atributosizes. Sem ele, o Next.js pode servir uma imagem enorme para um dispositivo móvel. - Formatos modernos: O Next.js serve WebP/AVIF automaticamente, mas certifique-se de que sua fonte original tem qualidade suficiente.
- LCP (Largest Contentful Paint): A imagem que é o LCP (geralmente o herói ou banner) deve ter a prop
priority. Isso diz ao navegador para carregá-la imediatamente, ignorando o lazy loading padrão.
// Ruim para LCP
<Image src="/hero.jpg" width={800} height={600} alt="Hero" />
// Bom para LCP
<Image src="/hero.jpg" width={800} height={600} alt="Hero" priority />2. Fontes e Layout Shift (CLS)
O Cumulative Layout Shift (CLS) é irritante e penaliza seu SEO. Fontes carregando tardiamente são causadoras frequentes.
- Use
next/font: Isso baixa a fonte no build time e a hospeda localmente (self-hosting), removendo o round-trip para o Google Fonts. - Use
display: swapouoptionalcom fallback fonts bem ajustadas.
3. Bundle Size e Dynamic Imports
O Next.js faz code splitting por rota automaticamente. Mas components pesados dentro de uma página (como um editor de texto rico, gráficos complexos ou mapas) devem ser carregados sob demanda.
import dynamic from 'next/dynamic'
const HeavyChart = dynamic(() => import('@/components/HeavyChart'), {
loading: () => <p>Carregando gráfico...</p>,
ssr: false // Se não precisar de SEO para esse componente
})4. Renderização: Server vs Client
A regra de ouro moderna (React Server Components): Mova o máximo possível para o servidor.
- Server Components: Zero JavaScript enviado para o cliente. Ótimo para renderizar markdown, buscar dados, etc.
- Client Components: Use apenas onde precisa de interatividade (
useState,useEffect, event listeners).
Quanto menos JS o navegador tiver que baixar, parsear e executar, melhor o TBT (Total Blocking Time) e o INP (Interaction to Next Paint).
Conclusão
Performance em Next.js é sobre aproveitar as ferramentas que o framework dá (Image, Font, Script) e tomar decisões conscientes sobre o que é renderizado onde. Monitore seus Core Web Vitals e trate regressões de performance como bugs críticos.