Marcio Cunha

Por que o build do Vite fica lento e como acelerar pacotes

Descubra como otimizar pacotes e aplicar divisão de código no Vite para reduzir o tempo de empacotamento da sua aplicação React moderna.

Marcio Cunha•6 min
Também disponível em:EnglishEspañol
Resumo
  • A divisão de código por rotas impede que o navegador baixe scripts desnecessários no primeiro acesso.
  • O uso correto de dependências pré-empacotadas evita gargalos no momento da transição para produção.
  • A configuração manual de chunks isola bibliotecas pesadas para maximizar o cache do navegador.
  • A análise detalhada de pacotes revela dependências ocultas que incham o tamanho final dos arquivos.
  • Ajustar os limites de aviso de tamanho ajuda a manter a saúde do projeto sob controle contínuo.

Por que o empacotamento de aplicações React começa a travar

Quando uma aplicação baseada em React cresce, o processo de empacotamento — conhecido como build — costuma desacelerar drasticamente. Ferramentas modernas como o Vite utilizam o esbuild por baixo dos panos para realizar transformações rápidas na fase de desenvolvimento, mas a etapa final de produção ainda depende do Rollup para gerar os arquivos otimizados. Na prática, isso significa que bibliotecas pesadas, ícones importados de forma incorreta e falta de divisão de código fazem o compilador gastar preciosos minutos unindo tudo em arquivos gigantescos.

Para entender o problema, imagine que você está organizando uma mudança e decide colocar todos os móveis, roupas e documentos dentro de uma única caixa gigantesca. O resultado óbvio é que carregar essa caixa se torna uma tarefa exaustiva. Em engenharia de software, o empacotamento monolítico gera um arquivo JavaScript principal que o navegador do usuário precisa baixar, ler e processar inteiro antes de exibir qualquer elemento na tela. Esse comportamento prejudica diretamente a experiência de navegação em dispositivos móveis e conexões instáveis.

A otimização de pacotes e a divisão de código entram exatamente para resolver esse gargalo logístico. Em vez de entregar o projeto inteiro de uma só vez, separamos o código em pequenos pedaços chamados de chunks. Assim, o navegador carrega apenas o que é estritamente necessário para a página atual, adiando o restante para momentos futuros. Se você gerencia infraestrutura e servidores web, sabe que otimizar o fluxo de dados reduz custos operacionais, assim como detalhamos em nosso guia sobre como calcular o consumo elétrico real do seu homelab. Na web, o princípio é o mesmo: gastar menos recursos para entregar o mesmo resultado.

Como aplicar a divisão de código com carregamento preguiçoso

A estratégia mais eficiente para reduzir o peso inicial de uma aplicação React é o chamado lazy loading, ou carregamento preguiçoso. Em vez de importar todos os componentes de páginas de forma síncrona no topo do arquivo principal, o React permite carregar rotas inteiras sob demanda usando a API nativa de importação dinâmica. Na prática, isso significa que a tela de painel administrativo só será baixada pelo navegador quando o usuário realmente clicar no botão para acessá-la.

Para implementar essa divisão no código, utilizamos as funções lazy e Suspense fornecidas pela própria biblioteca React. Veja um exemplo prático de como estruturar as rotas principais utilizando essa abordagem para que o compilador saiba exatamente onde separar os arquivos:

import React, { lazy, Suspense } from 'react';

const Dashboard = lazy(() => import('./pages/Dashboard'));
const Settings = lazy(() => import('./pages/Settings'));

function App() {
  return (
    
      <Routes>
        <Route path='/dashboard' element={<Dashboard />} />
        <Route path='/settings' element={<Settings />} />
      <>
    </Suspense>
  );
}

Quando o Vite analisa esse código durante o build, ele entende que './pages/Dashboard' e './pages/Settings' devem virar arquivos separados na pasta de distribuição. Isso reduz o arquivo principal a uma fração do seu tamanho original, acelerando a entrega inicial e melhorando as métricas de performance do site.

Configurando o Rollup para otimizar a divisão de chunks manuais

Por padrão, o Vite agrupa dependências de terceiros de forma automática, mas essa heurística nem sempre atinge o cenário ideal para aplicações complexas. Bibliotecas grandes como o framework de interface ou utilitários de gráficos podem acabar misturadas ao código da sua regra de negócio. Para assumir o controle total dessa distribuição, podemos ajustar o arquivo de configuração vite.config.js e definir regras manuais para separar os pacotes em arquivos isolados.

A separação manual traz uma vantagem colossal chamada cache de longo prazo. Quando você atualiza um texto ou um pequeno componente na sua aplicação, apenas o arquivo correspondente à sua regra de negócio sofre alteração no nome do arquivo gerado. As bibliotecas de terceiros, que raramente mudam, continuam armazenadas no cache do navegador do usuário, acelerando drasticamente as visitas recorrentes. O ajuste fino de parâmetros de compilação exige o mesmo cuidado analítico que aplicamos ao diagnosticar problemas de desempenho em servidores, como explicamos em como eliminar gargalos de I/O no ZFS.

Veja um exemplo prático de configuração no arquivo vite.config.js para isolar módulos pesados em arquivos dedicados:

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  build: {
    rollupOptions: {
      output: {
        manualChunks(id) {
          if (id.includes('node_modules')) {
            if (id.includes('react') || id.includes('react-dom')) {
              return 'vendor-react';
            }
            return 'vendor-libs';
          }
        }
      }
    }
  }
});

Com essa configuração, todas as dependências do React ficam agrupadas em um único arquivo chamado vendor-react, enquanto o restante das bibliotecas vai para vendor-libs. Se houver falhas de memória ou gargalos no ambiente de desenvolvimento ou CI/CD durante esses builds complexos, vale a pena monitorar o uso de recursos de forma parecida com a investigação de vazamentos detalhada em Node.js consumindo muita memória e como achar vazamentos.

Identificando dependências ocultas e pesadas no projeto

Muitas vezes, o aumento no tempo de build e no tamanho dos arquivos ocorre devido a importações malfeitas de bibliotecas populares. Um erro clássico é importar uma biblioteca inteira de ícones ou utilitários matemáticos quando apenas uma única função é utilizada no projeto. Na prática, isso força o compilador a empacotar milhares de linhas de código inútil que jamais serão executadas pelo usuário final.

Para solucionar esse problema, utilize ferramentas de análise visual de pacotes, como o rollup-visualizer, que gera um mapa interativo em formato de árvore mostrando exatamente quais arquivos estão ocupando mais espaço. Ao inspecionar esse mapa gráfico, você consegue identificar rapidamente dependências duplicadas, versões antigas conflitantes e pacotes que podem ser substituídos por alternativas nativas mais leves em JavaScript moderno.

Manter o projeto limpo e enxuto é um processo contínuo que exige disciplina da equipe de desenvolvimento. Sempre que for adicionar uma nova dependência ao projeto, pergunte-se se a funcionalidade realmente justifica o peso extra adicionado ao pacote final. Muitas vezes, um trecho simples de código nativo substitui com folga uma biblioteca inteira de terceiros.

Conclusão e boas práticas para manter o build ágil

Acelerar o build de aplicações React com o Vite não depende de uma única mágica, mas sim da combinação de boas práticas arquiteturais. Desde o uso correto de carregamento preguiçoso por rotas até a divisão manual de chunks e a auditoria constante de dependências, cada ajuste contribui para um ciclo de desenvolvimento muito mais produtivo e uma entrega final extremamente rápida para o usuário.

Adotar essas rotinas no dia a dia da engenharia de software elimina o desgaste com esperas prolongadas nas pipelines de integração contínua. Monitore sempre o tamanho dos arquivos gerados após cada grande atualização e mantenha seu ecossistema atualizado para aproveitar ao máximo as melhorias contínuas de performance entregues pelo ecossistema do Vite e do Rollup.