Pular para o conteúdo
  • Sites
  • Next.js 16
  • Cache Components
  • Turbopack
  • proxy.ts
  • migração

Next.js 16 na prática: Cache Components, Turbopack e proxy.ts - migrei, quebrou, aprendi

Migrei para Next.js 16 e quebrei 6 coisas antes de acertar: Cache Components com use cache, Turbopack padrão, proxy.ts no lugar do middleware e checklist de migração em 1 dia, com código.

Código de programação aberto na tela de um notebook.

Migrei um projeto real para o Next.js 16 na segunda, quebrei o build na terça e entendi o recado na quarta: o changelog conta o que mudou, não o que quebra em produção. Este guia é a versão que eu queria ter lido antes, com a base 16.0, o que a estável 16.3 entregou de verdade, o que o canary 16.4 testa agora e as 6 correções na ordem certa.

Aqui vale a tese que carrego há 20 anos entre design e código: tutorial acaba no exemplo, projeto de cliente começa nele. Cada seção abaixo termina com o gancho de dinheiro, porque feature técnica que não vira deploy mais barato ou conversão maior é só ruído.

Key Takeaways

  • Next.js 16.3 é a estável atual: Turbopack padrão com queda de RAM de 21,5 GB para 2 GB e build incremental até 5,5x mais rápido (Mercadodeti, 2026).
  • Cache Components com use cache e partialPrefetching liberam Instant Navigations e +22% de req sob carga via streams Node (Mercadodeti, 2026).
  • proxy.ts substitui middleware.ts no Node runtime; params, cookies() e headers() viraram async e quebram o build sem await (Código Sintético; Gautam Khorana, 28/08/2026).
  • Canary 16.4.26 e 16.4.27 (10 e 11/set/2026) testam Bundle Analyzer com tabelas, imgOptMozjpeg e strictRouteMatching que exige default.tsx (Promovaweb, 2026).

O que mudou no Next.js 16 que afeta quem vende site?

A base 16.0 trocou o motor e o modelo mental: Turbopack virou o bundler padrão, Cache Components com use cache virou a forma oficial de cachear, proxy.ts substituiu middleware.ts no Node runtime, React 19.2 trouxe View Transitions, Activity e useEffectEvent, React Compiler 1.0 ficou estável mas opt-in, com Node 20.9+ e TS 5.1+ como piso, e AMP mais next lint foram removidos (Next.js blog 16.0). A estável 16.3 acelerou tudo com Turbopack -90% de RAM, build incremental até 5,5x e +22% de req sob carga, somou Instant Navigations, AGENTS.md auto-gerado e depreciou o Edge Runtime (Mercadodeti, 2026).

Gancho cliente: motor novo não é vaidade. Build incremental de minutos para segundos significa preview barato por PR e deploy sem fila em dia de campanha. Navegação instantânea segura o visitante no catálogo em vez de perder ele no carregamento entre páginas.

O canary conta o futuro próximo, com etiqueta de risco. As versões 16.4.26 e 16.4.27, publicadas em 10 e 11 de setembro de 2026, testam Bundle Analyzer com tabelas de módulos, a flag imgOptMozjpeg para JPEG otimizado e o strictRouteMatching que passa a exigir default.tsx em rotas com paralelismo (Promovaweb, diários de 10 e 11/set/2026). Nada disso entra em produção de cliente sem travar a versão e ler o diff do dia.

Quadro ilustrado da migração para Next.js 16

Para o plano completo de site que converte, volte ao guia pilar site que vende todo dia.

Cache Components e use cache: quando liga, quando desliga?

Cache Components é o modelo de cache explícito do Next.js 16: nada é cacheado por acidente, tudo que pode ser estático leva a diretiva use cache com tempo de revalidação declarado, e o roteador usa partialPrefetching para pré-carregar o estático e completar o dinâmico na navegação, o que a Vercel chama de Instant Navigations (Next.js blog 16.0; Mercadodeti, 2026). Se a página mostra preço, estoque ou nome do usuário, você marca o estático com cache e deixa o dinâmico fluir sem ele.

Gancho cliente: navegação instantânea é conversão. Catálogo que troca de página sem spinner segura comparação de produto, e comparação segurada vira pedido no WhatsApp.

O erro clássico é confiar no fetch com cache implícito do Next 14 e 15. No modelo novo, defina revalidate de forma explícita ou assuma comportamento dinâmico. Este é o padrão mínimo que uso em página de serviço:

// app/servicos/page.tsx
export default async function ServicosPage() {
  'use cache';
  // Revalida o HTML estático a cada hora; o dinâmico entra via Suspense
  const res = await fetch('https://api.exemplo.com/servicos', {
    next: { revalidate: 3600 },
  });
  if (!res.ok) throw new Error('Falha ao carregar servicos');
  const servicos = (await res.json()) as { slug: string; titulo: string }[];
  return (
    <ul>
      {servicos.map((s) => (
        <li key={s.slug}>{s.titulo}</li>
      ))}
    </ul>
  );
}

Regra de bolso: ligue use cache em conteúdo editorial e vitrine, desligue em carrinho, saldo, dashboard e qualquer coisa por usuário. Cache em dado pessoal não é otimização, é vazamento com etapa extra.

Turbopack como padrão: build e dev que custam menos

O Turbopack saiu de opt-in para padrão no Next.js 16, e a estável 16.3 trouxe os números que importam para bolso: queda de RAM de 21,5 GB para 2 GB com memory eviction mais cache em disco, build incremental até 5,5x mais rápido e +22% de requisições sob carga via streams do Node (Mercadodeti, cobertura da 16.3, 2026). Na prática diária, o dev server sobe mais rápido, o hot reload acompanha arquivo grande e o CI para de estourar memória em monorepo.

Gancho cliente: CI que consome menos RAM e build que roda 5x mais rápido reduzem minuto de pipeline e hora de dev parado. Em agência com 10 deploys por semana, isso aparece na fatura do provedor e no prazo da campanha.

RAM do build antes e depois do Turbopack na 16.3

Queda de RAM do build com Turbopack na estável 16.3.

Build cold versus incremental na 16.3

Build incremental até 5,5x mais rápido na 16.3.

Quando voltar ao webpack: só com plugin sem suporte no Turbopack e com teste provando a falta. Fora isso, padrão é Turbopack e o next.config.ts fica limpo:

// next.config.ts
import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  reactStrictMode: true,
  poweredByHeader: false,
  // Turbopack e padrao na 16; experimental.turbo nao e mais necessario
};

export default nextConfig;

proxy.ts substitui middleware.ts: como migrei sem derrubar rota

O middleware.ts saiu de cena e o proxy.ts assumiu como ponto de interceptação de requisições no Node runtime, com a mesma ideia de matcher por rota e com acesso a cookies() e headers() async (Next.js blog 16.0; Código Sintético, 2026). Na migração, o passo é renomear o arquivo, trocar a assinatura para proxy e revisar cada leitura de cookie e header com await.

Gancho cliente: redirecionamento de campanha, bloqueio de rota e teste A/B moram aqui. Migração errada derruba justamente a página do anúncio pago, então este arquivo merece deploy em horário calmo com rollback pronto.

// proxy.ts (raiz do projeto, substitui middleware.ts)
import { NextResponse, type NextRequest } from 'next/server';

export function proxy(request: NextRequest) {
  const url = request.nextUrl.clone();
  // Exemplo: redireciona campanha antiga para a oferta atual
  if (url.pathname === '/promo-antiga') {
    url.pathname = '/oferta';
    return NextResponse.redirect(url);
  }
  return NextResponse.next();
}

export const config = {
  matcher: ['/promo-antiga', '/conta/:path*'],
};

Três detalhes que pegam: o Edge Runtime foi depreciado na 16.3, então revise qualquer runtime = 'edge' e mova lógica para Node; matcher amplo demais intercepta asset estático e piora LCP; e lógica pesada no proxy atrasa toda navegação, então deixe ele magro e jogue regra de negócio para Route Handler.

As 6 quebras que me pegaram na migração (e a correção)

Estas são as 6 quebras que quebraram meu build, na ordem em que apareceram, com a correção que funcionou e a fonte de cada comportamento (Código Sintético, 2026; Gautam Khorana, guia de migração de 28/08/2026). Rode uma por vez e confirme o build entre elas.

  1. params e searchParams viraram async. Página dinâmica que lia params.id direto agora precisa de await. Correção abaixo.
  2. cookies() e headers() viraram async. Todo cookies().get() sem await falha. Correção abaixo.
  3. fetch sem cache implícito. Defina next: { revalidate } ou cache: 'no-store' para dado vivo, senão o conteúdo nasce velho.
  4. Parallel routes exigem default.js. Slot @modal ou @painel sem default.js quebra navegação; no strictRouteMatching do canary 16.4 a exigência inclui default.tsx (Promovaweb, 11/set/2026).
  5. ReactDOM.render removido quebra libs antigas. Rode npm ls react e npm ls react-dom, atualize ou troque a lib que ainda usa a API legada. forwardRef virou desnecessário no React 19, simplifique o componente em vez de manter o wrapper.
  6. next lint e AMP removidos. Rode o ESLint direto (npx eslint .) e remova qualquer amp: true do config, que agora falha.
// app/blog/[slug]/page.tsx - params async na 16
export default async function PostPage({
  params,
}: {
  params: Promise<{ slug: string }>;
}) {
  const { slug } = await params;
  return <h1>Post: {slug}</h1>;
}
// Leitura de cookie e header com await na 16
import { cookies, headers } from 'next/headers';

export async function getSessao() {
  const cookieStore = await cookies();
  const headerStore = await headers();
  return {
    sessao: cookieStore.get('sessao')?.value ?? null,
    origem: headerStore.get('referer'),
  };
}

Erro de build no terminal durante migração para Next.js 16

Checklist de migração em 1 dia (ordem que funciona)

Faça nesta ordem e não pule etapa: crie branch e trave a versão no package.json, suba engines para Node 20.9+ e TS 5.1+, atualize React e ReactDOM juntos e rode npm ls react para caçar duplicata, corrija todo params, cookies() e headers() para async, migre middleware.ts para proxy.ts com matcher enxuto, remova next lint e AMP, adicione default.js nos slots paralelos e só no fim ligue use cache com revalidate nas páginas editoriais. Meça antes e depois com o mesmo cenário de build para provar o ganho em vez de declarar vitória.

Se a velocidade ainda trava conversão depois da migração, siga para o checklist Core Web Vitals que vira conversão. Se o site ficou rápido mas parado, complete com motion que vende sem matar performance.

Perguntas frequentes

Posso pular direto para a 16.3 sem passar pela 16.0?

Pode, e é o caminho que recomendo para projeto novo: instale a estável 16.3 direto e aplique o checklist async mais proxy desde o primeiro commit. Para projeto em produção no 15, suba primeiro para 16.0 em branch, estabilize, e só então avance para 16.3, porque misturar troca de major com tuning de cache dificulta achar o culpado quando algo quebra.

proxy.ts funciona no Edge?

Não como antes. O Edge Runtime foi depreciado na 16.3 e o proxy.ts roda no Node runtime por padrão (Mercadodeti, 2026). Se seu middleware antigo dependia de geolocalização de edge ou resposta em borda, revalide a arquitetura antes de migrar e mova o que for crítico para Route Handler ou para a CDN com teste de latência real.

Cache Components pode quebrar conteúdo dinâmico?

Pode, se você cachear o que muda por usuário. use cache em página com nome, saldo ou carrinho serve dado de um visitante para outro. A regra é simples: cache no editorial e na vitrine com revalidate declarado, cache: 'no-store' ou Suspense no que é pessoal, e teste logado com dois usuários diferentes antes de comemorar o TTFB baixo.

Conclusão

  • Next.js 16.3 estável entrega Turbopack padrão com -90% de RAM, build incremental até 5,5x e +22% de req sob carga (Mercadodeti, 2026).
  • Cache Components com use cache e partialPrefetching viram navegação instantânea quando o dinâmico fica fora do cache.
  • proxy.ts substitui middleware.ts no Node; params, cookies() e headers() exigem await.
  • Canary 16.4.26/.27 testa Analyzer com tabelas, imgOptMozjpeg e strictRouteMatching (Promovaweb, 10-11/set/2026). Canary se observa, não se entrega em produção de cliente.