Analise de bundle com Claude Code para Vite, Astro e Next.js
Analise bundles JS, dependencias duplicadas, dynamic import e orcamento CI com Claude Code.
Um bundle JavaScript raramente fica pesado por causa de uma unica mudanca ruim. Ele cresce com decisoes razoaveis: grafico no painel, editor rico, biblioteca de datas, mapa, video, SDK de autenticacao e codigo de A/B test. O problema nao e ter esses recursos. O problema e entregar tudo na primeira visita para pessoas que ainda nao precisam deles.
Analise de bundle e abrir o resultado de producao e perguntar: “o que estamos mandando para o navegador?”. Para iniciantes, pense em pesar uma mala e depois descobrir quais itens deixam a mala pesada. Claude Code ajuda muito, mas a tarefa precisa incluir medicao, diagnostico, mudanca pequena, verificacao e orcamento no CI.
Este guia cobre projetos Vite, Astro e semelhantes a Next.js. Vamos usar rollup-plugin-visualizer, source-map-explorer, checagem de dependencias duplicadas, dynamic import, bundle budget no CI e revisao com Claude Code. Para complementar, leia code splitting, tree shaking e otimizacao de performance.
Fluxo de trabalho
Os tamanhos mais comuns sao raw, gzip e brotli. Raw ajuda a ler diagramas. Gzip e brotli ficam mais proximos do trafego real. Mesmo assim, uma dependencia pode compactar bem e ainda custar caro para parsear e executar.
flowchart LR
A["production build"] --> B["visual report"]
B --> C["duplicate packages"]
C --> D["replace or dedupe"]
B --> E["route-level split"]
D --> F["bundle budget in CI"]
E --> F
F --> G["Claude Code review"]
Use referencias oficiais: Vite Building for Production, Astro Analyze bundle size, Next.js Package Bundling, web.dev Performance budgets 101 e documentacao Claude Code.
Visualizar Vite e Astro
Em Vite, comece com rollup-plugin-visualizer. Ele gera um HTML com treemap para ver os modulos pesados.
npm install -D rollup-plugin-visualizer
// vite.config.ts
import { defineConfig } from "vite";
import { visualizer } from "rollup-plugin-visualizer";
export default defineConfig({
plugins: [
visualizer({
filename: "dist/bundle-stats.html",
template: "treemap",
gzipSize: true,
brotliSize: true,
open: false
})
],
build: {
sourcemap: true,
rollupOptions: {
output: {
manualChunks: {
react: ["react", "react-dom"],
charts: ["recharts"],
editor: ["@tiptap/react", "@tiptap/starter-kit"]
}
}
}
}
});
No Astro, coloque em vite:
// astro.config.mjs
import { defineConfig } from "astro/config";
import { visualizer } from "rollup-plugin-visualizer";
export default defineConfig({
vite: {
plugins: [
visualizer({
filename: "dist/bundle-stats.html",
template: "treemap",
gzipSize: true,
brotliSize: true
})
],
build: { sourcemap: true }
}
});
npm run build
open dist/bundle-stats.html
No Windows PowerShell:
start dist/bundle-stats.html
Procure codigo que nao pertence ao primeiro carregamento: graficos de admin, editores, mapas, video, processamento Markdown, bibliotecas de data e UI interna.
Source maps e Next.js
source-map-explorer usa JS gerado e source maps para mostrar a origem do bundle.
npm install -D source-map-explorer
npm run build
npx source-map-explorer "dist/assets/*.js" --html dist/source-map-report.html
Em Next.js, confirme versao e builder antes de copiar uma receita antiga. Quando fizer sentido, use @next/bundle-analyzer.
// next.config.mjs
import bundleAnalyzer from "@next/bundle-analyzer";
const withBundleAnalyzer = bundleAnalyzer({
enabled: process.env.ANALYZE === "true"
});
export default withBundleAnalyzer({
reactStrictMode: true
});
npm install -D @next/bundle-analyzer
ANALYZE=true npm run build
PowerShell:
$env:ANALYZE="true"; npm run build
Dependencias duplicadas
Bibliotecas grandes aparecem rapido no grafico. Duplicatas sao mais silenciosas: duas versoes de date-fns, lodash junto com lodash-es, ou peer dependencies desalinhadas.
npm ls date-fns lodash lodash-es
npm dedupe
Com pnpm:
pnpm why date-fns
pnpm dedupe
Prompt recomendado:
Analise o production bundle deste repositorio.
1. Liste dependencias pesadas usando dist/bundle-stats.html ou source-map-explorer
2. Use npm ls ou pnpm why para encontrar pacotes duplicados
3. Separe candidatos em replace, dedupe, dynamic import e remove
4. Preserve UI, texto SEO, CTAs e eventos analytics
5. Faca a menor mudanca segura e rode npm run build mais bundle budget check
| Causa | Correcao | Verificacao |
|---|---|---|
moment no site todo | Intl.DateTimeFormat ou helper menor | fuso e idioma |
import completo de lodash | import por funcao ou API nativa | ESM/CommonJS |
| editor so de admin | carregar apos clique | loading e erro |
| graficos na home | separar relatorios | layout responsivo |
| versoes duplicadas | dedupe ou alinhar versoes | peer dependency |
dynamic import
dynamic import nao apaga codigo; ele muda o momento do carregamento. Serve para relatorios, editores, mapas e modais pouco usados.
// src/features/reports/ReportsButton.tsx
import { useState } from "react";
export function ReportsButton() {
const [html, setHtml] = useState<string>("");
const [loading, setLoading] = useState(false);
async function handleClick() {
setLoading(true);
const { renderRevenueReport } = await import("./renderRevenueReport");
setHtml(renderRevenueReport([12000, 18400, 9300]));
setLoading(false);
}
return (
<section>
<button type="button" onClick={handleClick} disabled={loading}>
{loading ? "Gerando relatorio" : "Ver relatorio de receita"}
</button>
<output aria-live="polite">{html}</output>
</section>
);
}
// src/features/reports/renderRevenueReport.ts
export function renderRevenueReport(values: number[]): string {
const total = values.reduce((sum, value) => sum + value, 0);
return `Total do mes: ${new Intl.NumberFormat("pt-BR").format(total)} BRL`;
}
Em Next.js, mantenha texto SEO, preco, links de compra e CTA de consultoria fora do chunk atrasado. Atrase apenas a UI pesada.
// app/admin/EditorSlot.tsx
"use client";
import dynamic from "next/dynamic";
const RichEditor = dynamic(() => import("./RichEditor"), {
ssr: false,
loading: () => <p aria-live="polite">Carregando editor...</p>
});
export function EditorSlot() {
return <RichEditor initialMarkdown="# Draft" />;
}
Orcamento em CI
Sem CI, o bundle volta a crescer. Este script falha quando o total gzip ou um arquivo individual passa do limite.
// scripts/check-bundle-budget.mjs
import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
import path from "node:path";
import { brotliCompressSync, gzipSync } from "node:zlib";
const targetDir = "dist/assets";
const maxTotalGzip = 220 * 1024;
const maxSingleGzip = 140 * 1024;
function walk(dir) {
return readdirSync(dir, { withFileTypes: true }).flatMap((entry) => {
const fullPath = path.join(dir, entry.name);
if (entry.isDirectory()) return walk(fullPath);
return /\.(js|css)$/.test(entry.name) ? [fullPath] : [];
});
}
if (!existsSync(targetDir)) {
console.error(`Missing ${targetDir}. Run npm run build first.`);
process.exit(1);
}
const rows = walk(targetDir).map((file) => {
const content = readFileSync(file);
return {
file,
raw: statSync(file).size,
gzip: gzipSync(content).byteLength,
brotli: brotliCompressSync(content).byteLength
};
});
const totalGzip = rows.reduce((sum, row) => sum + row.gzip, 0);
const tooLarge = rows.filter((row) => row.gzip > maxSingleGzip);
if (totalGzip > maxTotalGzip || tooLarge.length > 0) {
console.error(`Bundle budget failed. total gzip=${totalGzip} bytes`);
process.exit(1);
}
console.log(`Bundle budget passed. total gzip=${totalGzip} bytes`);
# .github/workflows/bundle-budget.yml
name: Bundle Budget
on: [pull_request]
jobs:
bundle-budget:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run build
- run: node scripts/check-bundle-budget.mjs
O primeiro limite deve ser realista. Pegue o gzip atual, adicione cerca de 10% e exija justificativa quando um PR ultrapassar.
Casos reais
Primeiro, dashboard SaaS. Lista, busca, navegacao e CTA principal devem aparecer rapido; graficos, logs de auditoria, CSV e relatorios de cobranca podem ficar em outro chunk.
Segundo, site de conteudo ou curso. Corpo do artigo, links de compra e CTA de consultoria devem renderizar cedo. Preview Markdown, recorte de imagens e painel de campanha podem esperar. Meça com analytics implementation.
Terceiro, landing page com mapa, video, calculadora ou formulario. A primeira tela mostra oferta, preco, prova e acao. Widgets pesados carregam no scroll ou clique. Veja tambem video player e acessibilidade.
Quarto, biblioteca UI interna. Um import de @company/ui pode carregar DatePicker, Modal, Chart e icones quando a pagina so usa Button. Divida exports e declare side effects de CSS ou tema.
Erros comuns
Nao meça dev build. Nao divida cada componente em chunks pequenos. Nao publique source maps sem politica clara. Nao deixe manualChunks sem revisao. E nao peca a Claude Code apenas para editar; peca tambem para revisar.
Revise este PR pelo ponto de vista de bundle analysis.
- As dependencias do first load sao necessarias?
- Existem versoes duplicadas?
- Os dynamic imports tem loading e error state?
- Texto SEO, preco, CTA e analytics ficaram fora dos chunks tardios?
- O log do budget ajuda a achar a causa?
- Resuma npm run build e os caminhos dos relatorios.
Monetizacao
Analise de bundle nao e so higiene tecnica. Se o primeiro render melhora, texto, produtos, materiais gratuitos e CTAs de consultoria aparecem antes. No ClaudeCodeLab isso afeta anuncios, venda de templates e pedidos de treinamento.
Para praticar, comece pela folha gratuita. Para prompts reutilizaveis, veja produtos. Para equipes que precisam organizar Vite, Astro, Next.js, CLAUDE.md, CI e review, use treinamento e consultoria Claude Code.
Verificacao pratica
Os exemplos foram conferidos em uma estrutura estilo Vite/React: o visualizer gera HTML, source-map-explorer precisa de source maps, e o script de budget usa apenas fs, path e zlib. A licao pratica foi separar conteudo critico de UI adiavel. Editores e graficos costumam ser bons candidatos; texto, preco, compra e CTA de consultoria geralmente nao.
Resumo
Um fluxo serio com Claude Code comeca por evidencia: build de producao, visualizacao, duplicatas, dynamic import, orcamento CI e review. Bundle analysis, tree shaking e code splitting sao uma unica rotina para manter a aplicacao rapida quando trafego e receita crescem.
PDF grátis: cheatsheet do Claude Code
Informe seu e-mail e baixe uma página com comandos, hábitos de revisão e workflows seguros.
Cuidamos dos seus dados e não enviamos spam.
Sobre o autor
Masa
Engenheiro focado em workflows práticos com Claude Code.
Artigos relacionados
Permission receipt no Claude Code: escopo, prova e rollback
Padrão de permission receipt para Claude Code: ações permitidas, limites de aprovação, comandos de prova, rollback e CTA de receita.
Agent Harness seguro para Claude Code e Codex: permissoes, verificacao e rollback
Monte uma base segura para agentes com Claude Code e Codex usando politicas, plano, verificacao e recuperacao.
Subagentes no Claude Code: guia prático para delegar trabalho com segurança
Guia prático de subagentes no Claude Code para dividir artigos e código: regras, prompts, riscos e checklist.