Abra a aba Network de uma aplicação Next.js e provavelmente vai aparecer uma coleção de arquivos JavaScript com nomes que parecem ter saído de um gerador de senhas. Aqueles arquivos são os chunks: pedaços do código da aplicação, das dependências e do runtime que o navegador baixa para montar cada página.
Separar o JavaScript em pedaços não é novidade. A parte interessante está em decidir o que entra em cada pedaço. Um chunk maior reduz o número de requisições, mas pode mandar código que aquela página não usa. Um chunk menor evita desperdício, porém aumenta o número de arquivos e pode reapresentar ao navegador código que ele já tinha baixado em outra combinação.
Em setembro, a equipe do Next.js publicou uma explicação detalhada de como o Turbopack faz essa escolha e apresentou opções experimentais do Next.js 16.3 para ajustar o processo. O material ajuda a enxergar chunking como um problema de tráfego e cache, não como uma caixa-preta que sempre melhora quando gera arquivos menores.
Um arquivo para tudo também tem um preço
A estratégia mais simples seria colocar todo o JavaScript da aplicação em um único arquivo. O primeiro acesso ficaria pesado, mas as páginas seguintes encontrariam esse bundle no cache. Isso pode funcionar em uma aplicação pequena. Conforme o projeto cresce, uma rota simples acaba pagando pelo editor de texto, pelo gráfico e pelo player de vídeo usados em áreas que o visitante talvez nunca abra.
No outro extremo, o bundler poderia gerar um arquivo para cada módulo. O navegador receberia somente os módulos necessários e reaproveitaria cada um deles entre as páginas. O problema muda de lugar: centenas de módulos viram centenas de requisições. HTTP/2 reduziu bastante o custo de fazer várias solicitações, mas esse custo não desapareceu. Arquivos minúsculos também aproveitam pior a compressão, porque há menos conteúdo repetido dentro de cada unidade.
Gerar um chunk por página parece um meio-termo, até dois caminhos diferentes usarem o mesmo componente. Se o rodapé estiver empacotado uma vez na página inicial e outra vez na documentação, o usuário baixa duas cópias do mesmo código ao navegar entre elas. O trabalho real do chunker é encontrar uma divisão que não exagere em nenhum desses três custos: bytes desnecessários, requisições demais e pouco reaproveitamento de cache.
O Turbopack pensa em grupos de chunks
O Turbopack organiza chunks em grupos carregados juntos. Uma rota forma um grupo; um import() dinâmico pode formar outro. Dentro de cada grupo, o bundler avalia quais arquivos pequenos vale a pena juntar. Como os itens daquele grupo já seriam necessários para a mesma navegação, a união reduz requisições sem acrescentar código estranho à página naquele primeiro momento.
A dificuldade aparece na navegação seguinte. Imagine que o chunk A contém um rodapé usado em todo o site e o chunk B contém um player usado somente na home. Juntar A e B economiza uma requisição quando a home abre. Se o visitante depois entra em uma página que precisa apenas do rodapé, o arquivo combinado não serve como substituto do A isolado. O navegador pode acabar baixando o código do rodapé outra vez.
Por isso, a decisão não depende apenas do tamanho de cada módulo. O algoritmo considera em quantos grupos A aparece sozinho, em quantos B aparece sozinho e em quantos os dois aparecem juntos. Também tenta estimar a chance de a sessão terminar na primeira página ou continuar em outra rota. É uma heurística, não uma leitura do futuro.
Os números mostram por que não existe configuração perfeita
A equipe comparou três estratégias no próprio site do Next.js durante uma sequência de oito páginas. Sem juntar chunks, o navegador transferiu 561,6 KiB em 96 requisições. Com a configuração padrão do Turbopack, foram 554,8 KiB em 38 requisições. Ao juntar tudo o que fosse possível dentro de cada grupo, o número caiu para 15 requisições, mas o volume subiu para 610 KiB.
O padrão reduziu as requisições em mais da metade sem aumentar os bytes transferidos naquele percurso. Já a junção agressiva venceu no carregamento inicial e perdeu conforme a navegação avançou, porque combinações maiores foram menos reutilizáveis. Isso não prova que os mesmos números aparecerão em qualquer aplicação. É um teste feito pela equipe no próprio site, com uma sequência específica de rotas. O valor está em deixar o conflito visível.
Component chunks tentam aproveitar o que já está no cache
Uma das experiências do Next.js 16.3 é gerar, ao mesmo tempo, o chunk combinado e suas partes menores. O runtime acompanha quais componentes o navegador já carregou e escolhe a alternativa mais barata para a próxima rota: buscar o arquivo inteiro ou baixar somente as partes ausentes. Se o usuário já recebeu A dentro de A+B, não deveria precisar buscar A novamente.
A opção fica em experimental.turbopackChunking e vem desativada. Um recorte da configuração seria:
import type { NextConfig } from 'next'
const nextConfig = {
experimental: {
turbopackChunking: {
generateComponentChunks: true,
minComponentChunkSize: 20_000,
},
},
} satisfies NextConfig
export default nextConfig
O limite mínimo evita transformar cada função pequena em um arquivo separado. Component chunks menores do que esse valor são agrupados, reduzindo o risco de trocar duplicação de código por uma chuva de requisições. A equipe também está experimentando o modo only-if-cached da Fetch API para consultar o cache HTTP sem recorrer automaticamente à rede. Esse modo exige requisições same-origin e responde com 504 quando não encontra uma entrada, então não é um botão genérico de “usar cache”.
Dados reais podem substituir parte dos palpites
O chunker precisa assumir como as pessoas navegam. A configuração padrão atribui peso de 0,67 ao primeiro carregamento, como se aproximadamente dois terços das sessões terminassem em uma página. É uma referência razoável para começar, mas não descreve igualmente um blog, um painel interno e um sistema usado durante oito horas por dia.
As novas opções permitem informar essa realidade ao algoritmo. firstPageLoadPriority muda o peso dado ao primeiro acesso; a própria documentação sugere a taxa de rejeição do site como aproximação. priorityRoutes identifica páginas cujo carregamento inicial merece mais atenção. clusters reúne rotas que costumam aparecer na mesma sessão, permitindo que o Turbopack seja mais agressivo ao combinar código compartilhado entre elas.
Isso cria uma ponte interessante entre RUM e build. Em vez de escolher a estratégia apenas pela intuição do time, dá para observar as rotas de entrada e os caminhos mais comuns. Ainda assim, copiar a taxa de rejeição do Analytics para a configuração e encerrar o assunto seria otimização por procuração. O que importa é medir o resultado entregue: bytes transferidos, número de requisições, acertos de cache e tempo de interação nas navegações reais.
Mandar menos código continua sendo melhor do que repartir desperdício
Chunking distribui o JavaScript que existe. Ele não corrige sozinho uma dependência pesada enviada ao cliente sem necessidade. As mudanças apresentadas também atacam esse lado: tree shaking experimental de módulos CommonJS, um runtime compartilhado entre páginas e um runtime padrão mais leve, que só inclui suporte a WebAssembly e Web Workers quando a aplicação realmente usa esses recursos.
Essa distinção evita uma armadilha comum. Uma aplicação pode exibir muitos arquivos pequenos na aba Network e ainda enviar pouco JavaScript; outra pode mostrar poucos arquivos e transferir centenas de kilobytes desnecessários. Contar chunks sem olhar tamanho, conteúdo e sequência de navegação diz pouco.
Vale mexer na configuração agora?
O Turbopack é o bundler padrão do Next.js desde a versão 16, mas isso não torna estáveis todas as opções ao redor dele. A documentação classifica experimental.turbopackChunking como experimental, sujeita a mudanças e não recomendada para produção. É um bom laboratório para quem consegue comparar builds e aceitar que nomes ou comportamentos podem mudar. Não é uma correção para aplicar às cegas porque apareceu uma nova chave no next.config.ts.
Antes de ajustar limites ou heurísticas, vale seguir uma sequência simples:
- identifique quais rotas realmente enviam JavaScript demais;
- use o Bundle Analyzer do Turbopack para encontrar dependências e cadeias de importação pesadas;
- grave um percurso representativo no DevTools, incluindo navegações internas;
- compare bytes, requisições e cache com a configuração padrão;
- teste uma mudança por vez em ambiente controlado;
- acompanhe métricas de usuários reais antes de transformar o experimento em padrão do projeto.
A parte mais útil desse trabalho do Turbopack talvez não seja uma opção específica. É a lembrança de que “bundle menor” e “site mais rápido” não são sinônimos automáticos. O navegador precisa baixar, descompactar, interpretar e executar arquivos enquanto o usuário percorre caminhos que o build só consegue estimar. Uma boa divisão de chunks reduz esse custo ao longo da sessão, não apenas na captura bonita da primeira página.
