Bundle-Analyse mit Claude Code fur Vite, Astro und Next.js
Analysiere JS-Bundles, doppelte Pakete, dynamic import und CI-Budgets mit Claude Code.
Ein JavaScript-Bundle wird selten durch einen einzigen Fehler riesig. Es wachst durch nachvollziehbare Features: ein Chart im Adminbereich, ein Rich-Text-Editor, eine Datumsbibliothek, eine Karte, ein Video-Player, ein Auth-SDK oder A/B-Test-Code. Diese Funktionen konnen sinnvoll sein. Das Problem entsteht, wenn sie schon beim ersten Seitenaufruf an alle Nutzer ausgeliefert werden.
Bundle-Analyse bedeutet, das Produktions-Build zu offnen und zu prufen, was der Browser wirklich bekommt. Einfach gesagt: Man wiegt den Koffer und schaut dann nach, welche Gegenstande ihn schwer machen. Claude Code kann Berichte lesen und Code andern, braucht aber einen klaren Auftrag mit Messung, Diagnose, kleiner Anderung, Verifikation und CI-Budget.
Dieser Leitfaden passt zu Vite, Astro und Next.js-ahnlichen Projekten. Er zeigt rollup-plugin-visualizer, source-map-explorer, doppelte Abhangigkeiten, dynamic import, ein Bundle-Budget in CI und eine Review-Schleife mit Claude Code. Passende Grundlagen sind Code Splitting, Tree Shaking und Performance Optimization.
Ablauf
Typische Werte sind raw, gzip und brotli. Raw hilft beim Lesen von Diagrammen. Gzip und brotli liegen naher am Netzwerktransfer. Trotzdem kann ein Paket mit guter Kompression teuer beim Parsen und Ausfuhren sein.
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"]
Nutze offizielle Quellen: Vite Building for Production, Astro Analyze bundle size, Next.js Package Bundling, web.dev Performance budgets 101 und die Claude Code Dokumentation.
Vite und Astro visualisieren
Bei Vite ist rollup-plugin-visualizer ein guter erster Schritt. Es erzeugt ein HTML-Treemap mit den schweren Modulen.
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"]
}
}
}
}
});
In Astro liegt die Konfiguration unter 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
Unter Windows PowerShell:
start dist/bundle-stats.html
Suche zuerst nach Code, der nicht in den ersten Viewport gehort: Admin-Charts, Editoren, Karten, Video-Player, Markdown-Prozessoren, schwere Datumslogik und interne UI.
Source Maps und Next.js
source-map-explorer nutzt JavaScript-Dateien und Source Maps, um die Herkunft im Bundle zu zeigen.
npm install -D source-map-explorer
npm run build
npx source-map-explorer "dist/assets/*.js" --html dist/source-map-report.html
Bei Next.js hangt der richtige Weg von Version und Builder ab. Prufe zuerst die offiziellen Hinweise und nutze bei passender Konfiguration @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
Doppelte Pakete finden
Grosse Libraries sieht man im Treemap. Doppelte Versionen sind unauffalliger: zwei date-fns-Versionen, lodash plus lodash-es, oder falsch ausgerichtete peer dependencies.
npm ls date-fns lodash lodash-es
npm dedupe
Mit pnpm:
pnpm why date-fns
pnpm dedupe
Ein guter Auftrag an Claude Code:
Analysiere das production bundle dieses Repos.
1. Liste schwere Abhangigkeiten aus dist/bundle-stats.html oder source-map-explorer
2. Nutze npm ls oder pnpm why fur doppelte Pakete
3. Teile Kandidaten in replace, dedupe, dynamic import und remove ein
4. Erhalte UI, SEO-Text, CTAs und Analytics-Events
5. Mache die kleinste sichere Anderung und fuhre npm run build plus bundle budget check aus
| Ursache | Losung | Prufung |
|---|---|---|
moment uberall | Intl.DateTimeFormat oder kleiner Helper | Zeitzone und Sprache |
kompletter lodash Import | Funktionsimport oder native API | ESM/CommonJS |
| Admin-Editor | nach Klick laden | Loading und Fehler |
| Charts auf Home | Reports trennen | Responsive Layout |
| doppelte Versionen | dedupe oder Versionen angleichen | peer dependency |
dynamic import
dynamic import entfernt keinen Code. Es verschiebt den Ladezeitpunkt. Das passt zu Reports, Editoren, Karten und seltenen Modalen.
// 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 ? "Report wird erstellt" : "Umsatzreport anzeigen"}
</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 `Monatssumme: ${new Intl.NumberFormat("de-DE").format(total)} EUR`;
}
In Next.js bleiben SEO-Text, Preise, Kauflinks und Beratungs-CTAs serverseitig sichtbar. Verzogert wird nur die schwere Editor-UI.
// app/admin/EditorSlot.tsx
"use client";
import dynamic from "next/dynamic";
const RichEditor = dynamic(() => import("./RichEditor"), {
ssr: false,
loading: () => <p aria-live="polite">Editor wird geladen...</p>
});
export function EditorSlot() {
return <RichEditor initialMarkdown="# Draft" />;
}
CI-Budget
Ohne Budget wachst das Bundle wieder. Dieses Skript schlagt fehl, wenn total gzip oder ein einzelnes Asset zu gross wird.
// 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
Setze das erste Budget nicht zu streng. Nimm den aktuellen gzip-Wert, gib etwa 10% Puffer und verlange eine Begrundung, wenn eine PR ihn uberschreitet.
Praxisfalle
Erstens: SaaS-Dashboard. Liste, Suche, Navigation und Haupt-CTA mussen schnell erscheinen. Admin-Charts, Audit-Logs, CSV-Export und Billing-Reports konnen eigene Chunks sein.
Zweitens: Content- oder Kursseite. Artikeltext, Kauflinks und Beratungs-CTA sollten fruh rendern. Markdown-Preview, Bildzuschnitt und Kampagnenverwaltung konnen warten. Messe die Wirkung mit Analytics Implementation.
Drittens: Landingpage mit Karte, Video, Rechner oder Formular. Der erste Viewport zeigt Angebot, Preis, Beweis und Aktion. Schwere Widgets laden nach Scroll oder Klick. Siehe auch Video Player und Accessibility.
Viertens: interne UI-Bibliothek. Ein Import aus @company/ui kann DatePicker, Modal, Chart und Icons laden, obwohl nur Button gebraucht wird. Trenne exports und deklariere CSS- oder Theme-Side-Effects.
Haufige Fehler
Miss kein dev build. Schneide nicht jede Komponente in einen eigenen Chunk. Veroffentliche Source Maps nicht ohne Sicherheitsentscheidung. Lasse manualChunks nicht jahrelang ungepruft. Und bitte Claude Code nicht nur um Anderung, sondern auch um Review.
Review diese PR aus Sicht der Bundle-Analyse.
- Sind First-Load-Abhangigkeiten notwendig?
- Gibt es doppelte Paketversionen?
- Haben dynamic imports loading und error state?
- Bleiben SEO-Text, Preise, CTA und Analytics ausserhalb spater Chunks?
- Hilft das Budget-Log bei der Ursachenanalyse?
- Fasse npm run build und Report-Pfade zusammen.
Monetarisierung
Bundle-Analyse ist nicht nur Technikpflege. Wenn der erste Render schneller ist, erscheinen Text, Produktlinks, kostenlose Ressourcen und Beratungs-CTAs fruher. Fur ClaudeCodeLab beeinflusst das Anzeigenumsatz, Template-Verkauf und Trainingsanfragen.
Einzelne starten mit dem kostenlosen Cheat Sheet. Wiederverwendbare Prompts und Templates stehen unter Produkte. Teams, die Vite, Astro, Next.js, CLAUDE.md, CI und Reviews zusammen strukturieren wollen, nutzen Claude Code Training und Beratung.
Verifikation
Die Beispiele wurden gegen eine Vite/React-artige Struktur gepruft: Visualizer schreibt HTML, source-map-explorer braucht Source Maps, und das Budget-Skript nutzt nur fs, path und zlib. Der wichtigste Punkt war nicht, jedes grosse Paket zu ersetzen. Entscheidend war die Trennung zwischen First-Load-Inhalt und spater ladbarer UI. Editoren und Charts sind gute Kandidaten; Text, Preise, Kauflinks und Beratungs-CTA meistens nicht.
Zusammenfassung
Ein belastbarer Claude-Code-Workflow beginnt mit Belegen: production build, Visualisierung, Dedupe-Prufung, dynamic import, CI-Budget und Review. Bundle analysis, tree shaking und code splitting sind ein gemeinsamer Betriebsprozess, damit eine App auch bei wachsendem Traffic und Umsatz schnell bleibt.
Kostenloses PDF: Claude-Code-Cheatsheet
E-Mail eintragen und eine Seite mit Befehlen, Review-Gewohnheiten und sicheren Workflows herunterladen.
Wir schützen Ihre Daten und senden keinen Spam.
Über den Autor
Masa
Engineer für praktische Claude-Code-Workflows und Team-Einführung.
Ähnliche Artikel
Claude-Code-Permission-Receipt: Scope, Beweis und Rollback festhalten
Permission-Receipt für Claude Code: erlaubte Aktionen, Freigabegrenzen, Prüfbefehle, Rollback und Umsatz-CTA-Prüfung.
Sicheres Agent Harness fur Claude Code und Codex: Rechte, Prufung und Rollback
Ein praktisches Agent Harness fur Claude Code und Codex mit Policy, Plan, Verifikation und Recovery.
Claude Code Subagents: Praxisleitfaden für sichere Agent-Delegation
Claude Code Subagents praktisch nutzen: Artikel- und Codearbeit sicher aufteilen, Prompts einsetzen, Fehler vermeiden.