Performance em Aplicações Next.js: Guia Completo
Performance
8 de janeiro de 2024
12 min de leitura

Performance em Aplicações Next.js: Guia Completo

Técnicas avançadas de otimização que aprendi trabalhando em aplicações com milhões de usuários no QuintoAndar e Netshoes.

#Next.js #React #Performance #Web Vitals #Otimização
Performance em Aplicações Next.js: Guia Completo

Performance em Aplicações Next.js: Guia Completo

Quando você trabalha em aplicações que recebem milhões de acessos, como no QuintoAndar e Netshoes, performance não é luxo - é necessidade. Aqui estão as técnicas que realmente funcionam em produção.

1. Image Optimization - O Game Changer

O componente Image do Next.js é revolucionário, mas precisa ser usado corretamente:

import Image from 'next/image';

// ❌ Evite
<img src="/hero.jpg" alt="Hero" />

// ✅ Faça assim
<Image
  src="/hero.jpg"
  alt="Hero"
  width={1200}
  height={600}
  priority // Para imagens above the fold
  placeholder="blur"
  blurDataURL="data:image/jpeg;base64,..."
/>

Resultados Reais:

  • -70% no tamanho das imagens
  • +40% no Largest Contentful Paint (LCP)
  • Lazy loading automático

2. Code Splitting Inteligente

Dynamic Imports para Componentes Pesados

import dynamic from "next/dynamic";

// ❌ Carrega tudo de uma vez
import HeavyChart from "../components/HeavyChart";

// ✅ Carrega apenas quando necessário
const HeavyChart = dynamic(() => import("../components/HeavyChart"), {
  loading: () => <div>Carregando gráfico...</div>,
  ssr: false, // Se não precisar de SSR
});

Bundle Analysis

# Instale o analisador
npm install @next/bundle-analyzer

# Analise seus bundles
ANALYZE=true npm run build

3. API Routes Otimizadas

Cache Strategies

// api/posts/[id].js
export default async function handler(req, res) {
  // Cache por 1 hora, stale-while-revalidate por 1 dia
  res.setHeader(
    "Cache-Control",
    "public, s-maxage=3600, stale-while-revalidate=86400"
  );

  const post = await getPost(req.query.id);
  res.json(post);
}

Database Query Optimization

// ❌ N+1 Query Problem
const posts = await Post.findAll();
for (const post of posts) {
  post.author = await User.findById(post.authorId);
}

// ✅ Single Query com Join
const posts = await Post.findAll({
  include: [{ model: User, as: "author" }],
});

4. Static Generation vs SSR

Quando usar cada um:

// ✅ Static Generation - Páginas que mudam pouco
export async function getStaticProps() {
  const posts = await getPosts();

  return {
    props: { posts },
    revalidate: 3600, // ISR - revalida a cada hora
  };
}

// ✅ SSR - Páginas com dados dinâmicos/personalizados
export async function getServerSideProps({ req }) {
  const session = await getSession(req);
  const userData = await getUserData(session.userId);

  return {
    props: { userData },
  };
}

5. Otimizações de Runtime

React.memo e useMemo Estratégicos

// ❌ Re-renderiza sempre
const ExpensiveComponent = ({ data, filters }) => {
  const filteredData = data.filter((item) => filters.includes(item.category));

  return <List items={filteredData} />;
};

// ✅ Otimizado
const ExpensiveComponent = React.memo(({ data, filters }) => {
  const filteredData = useMemo(
    () => data.filter((item) => filters.includes(item.category)),
    [data, filters]
  );

  return <List items={filteredData} />;
});

6. Web Vitals em Produção

Monitoring Real User Metrics

// _app.js
export function reportWebVitals(metric) {
  // Envie para seu analytics
  analytics.track("Web Vital", {
    name: metric.name,
    value: metric.value,
    id: metric.id,
  });
}

Métricas que Realmente Importam:

  • LCP < 2.5s (Largest Contentful Paint)
  • FID < 100ms (First Input Delay)
  • CLS < 0.1 (Cumulative Layout Shift)

7. Deployment e CDN

Vercel Configuration

// next.config.js
module.exports = {
  experimental: {
    optimizeCss: true,
  },
  images: {
    domains: ["example.com"],
    formats: ["image/webp", "image/avif"],
  },
  compress: true,
  swcMinify: true,
};

Resultados Medidos

Implementando essas técnicas no QuintoAndar:

  • Performance Score: 65 → 95
  • LCP: 4.2s → 1.8s
  • Bundle Size: -45%
  • Time to Interactive: -60%

Ferramentas Essenciais

  1. Lighthouse - Auditoria básica
  2. WebPageTest - Análise detalhada
  3. Bundle Analyzer - Análise de bundles
  4. React DevTools Profiler - Profile de componentes

Conclusão

Performance é um processo contínuo. Estabeleça métricas, monitore constantemente e otimize baseado em dados reais de usuários.

Próximo passo: Implementar uma estratégia de monitoring para acompanhar essas métricas em produção.


Qual técnica você achou mais útil? Tem alguma dúvida sobre implementação? Compartilhe nos comentários!

Logo Renato Khael

Renato Khael

Engenheiro de Software

Gostou do artigo?

Vamos conversar sobre seu próximo projeto ou trocar ideias sobre tecnologia

WhatsApp