Analyse de bundle avec Claude Code pour Vite, Astro et Next.js
Analysez les bundles JS, doublons de dependances, dynamic import et budgets CI avec Claude Code.
Un bundle JavaScript grossit rarement a cause d’un seul mauvais commit. Il grossit avec des ajouts utiles: un graphique pour l’admin, un editeur riche, une librairie de dates, une carte, une video, un SDK d’authentification ou un test A/B. Le probleme n’est pas que ces fonctions soient inutiles. Le probleme est de les envoyer des la premiere vue a des visiteurs qui n’en ont pas encore besoin.
Analyser un bundle consiste a ouvrir le resultat de production et a verifier ce que le navigateur recoit vraiment. Pour debuter, imaginez une valise: on la pese, puis on regarde quels objets prennent le plus de place. Claude Code peut aider a lire les rapports et modifier le code, mais il faut lui donner une methode: mesure, diagnostic, changement minimal, verification et budget CI.
Ce guide couvre Vite, Astro et les projets proches de Next.js. Nous allons utiliser rollup-plugin-visualizer, source-map-explorer, la recherche de dependances dupliquees, dynamic import, un budget de bundle en CI et une revue Claude Code. A lire avec code splitting, tree shaking et optimisation de performance.
Workflow de base
Les tailles courantes sont raw, gzip et brotli. Raw aide a lire les diagrammes. Gzip et brotli se rapprochent du transfert reseau. Mais une librairie qui se compresse bien peut encore couter cher a parser et executer.
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"]
Gardez les sources officielles ouvertes: Building for Production pour Vite, Analyze bundle size pour Astro, Package Bundling pour Next.js, Performance budgets 101 et la documentation Claude Code.
Visualiser Vite et Astro
Dans Vite, rollup-plugin-visualizer donne rapidement une carte HTML des modules les plus lourds.
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"]
}
}
}
}
});
Dans Astro, placez-le sous 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
Sur Windows PowerShell:
start dist/bundle-stats.html
Cherchez les elements inutiles au premier affichage: graphiques d’admin, editeur, carte, lecteur video, transformation Markdown, grosse librairie de dates, UI interne.
Source maps et Next.js
source-map-explorer utilise les fichiers JS et leurs source maps pour montrer l’origine du bundle.
npm install -D source-map-explorer
npm run build
npx source-map-explorer "dist/assets/*.js" --html dist/source-map-report.html
Avec Next.js, verifiez la version et le builder avant de copier une recette. Selon le projet, l’analyse officielle ou @next/bundle-analyzer sera adaptee.
// 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
Doublons de dependances
Les grosses dependances sautent aux yeux. Les doublons sont plus discrets: deux versions de date-fns, lodash et lodash-es en meme temps, ou une librairie UI avec une peer dependency mal alignee.
npm ls date-fns lodash lodash-es
npm dedupe
Avec pnpm:
pnpm why date-fns
pnpm dedupe
Prompt utile:
Analyse le bundle de production de ce repo.
1. Liste les dependances lourdes depuis dist/bundle-stats.html ou source-map-explorer
2. Utilise npm ls ou pnpm why pour trouver les doublons
3. Classe les actions en replace, dedupe, dynamic import et remove
4. Preserve l'UI, le texte SEO, les CTA et les evenements analytics
5. Fais le plus petit changement sur et lance npm run build puis le budget bundle
| Cause | Correction | Verification |
|---|---|---|
moment partout | Intl.DateTimeFormat ou helper plus petit | fuseau horaire et langue |
import complet de lodash | import par fonction ou API native | ESM/CommonJS |
| editeur admin | charger apres clic | loading et erreur |
| graphiques sur l’accueil | separer les rapports | responsive |
| versions dupliquees | dedupe ou alignement | peer dependency |
dynamic import
dynamic import ne supprime pas le code. Il repousse son chargement jusqu’au moment utile. C’est adapte aux rapports, editeurs, cartes et modales rares.
// 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 ? "Generation du rapport" : "Voir le rapport de revenus"}
</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 du mois: ${new Intl.NumberFormat("fr-FR").format(total)} EUR`;
}
Dans Next.js, gardez le texte SEO, les prix, les liens d’achat et les CTA de consultation visibles cote serveur. Retardez seulement l’editeur lourd.
// app/admin/EditorSlot.tsx
"use client";
import dynamic from "next/dynamic";
const RichEditor = dynamic(() => import("./RichEditor"), {
ssr: false,
loading: () => <p aria-live="polite">Chargement de l'editeur...</p>
});
export function EditorSlot() {
return <RichEditor initialMarkdown="# Draft" />;
}
Budget CI
Sans budget, la taille remonte. Ce script echoue si le total gzip ou un fichier depasse la 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
Le premier budget doit etre realiste. Prenez la taille gzip actuelle, ajoutez environ 10%, puis demandez une justification si une PR depasse la limite.
Cas concrets
Premier cas: un dashboard SaaS. Liste, recherche, navigation et CTA principal doivent charger vite. Graphiques, logs d’audit, export CSV et facturation peuvent etre separes.
Deuxieme cas: un site de contenu ou de formation. Le corps de l’article, les liens d’achat et le CTA de consultation doivent apparaitre tot. La preview Markdown, le recadrage d’images et l’administration de campagnes peuvent attendre. Mesurez l’effet avec analytics implementation.
Troisieme cas: une landing page avec carte, video, calculateur ou formulaire. La premiere vue garde l’offre, le prix, la preuve et l’action. Les widgets lourds chargent au scroll ou au clic. Consultez aussi video player et accessibilite.
Quatrieme cas: une bibliotheque UI interne. Un import @company/ui peut charger DatePicker, Modal, Chart et tout le pack d’icones pour un simple Button. Separez les exports et declarez les side effects CSS ou theme.
Pieges frequents
Ne mesurez pas un dev build. Ne decoupez pas chaque composant en chunk. Ne publiez pas les source maps sans politique claire. Ne gardez pas manualChunks sans revue. Et ne demandez pas seulement a Claude Code de modifier: demandez-lui aussi de verifier.
Review cette PR sous l'angle bundle analysis.
- Les dependances du first load sont-elles necessaires?
- Existe-t-il des versions dupliquees?
- Les dynamic imports ont-ils loading et error state?
- Texte SEO, prix, CTA et analytics restent-ils hors des chunks tardifs?
- Le log du budget permet-il de trouver la cause?
- Resume npm run build et les chemins des rapports.
Monetisation
L’analyse de bundle n’est pas seulement de l’hygiene technique. Si le premier rendu est plus rapide, le contenu, les produits, les ressources gratuites et les CTA de consultation apparaissent plus tot. Pour ClaudeCodeLab, cela touche la publicite, les ventes de templates et les demandes de formation.
Pour pratiquer, commencez par la fiche gratuite. Pour des prompts reutilisables, voyez produits. Pour une equipe qui veut cadrer Vite, Astro, Next.js, CLAUDE.md, CI et review, passez par formation et consultation Claude Code.
Verification pratique
Les exemples ont ete verifies contre une structure de type Vite/React: le visualizer produit un rapport HTML, source-map-explorer a besoin de source maps, et le script de budget utilise seulement fs, path et zlib. La lecon principale est de separer ce qui doit apparaitre au premier rendu de ce qui peut attendre. Les editeurs et graphiques sont de bons candidats; le texte, les prix, les liens d’achat et les CTA le sont rarement.
Resume
Un bon workflow Claude Code commence par des preuves: build de production, visualisation, doublons, dynamic import, budget CI et review. Bundle analysis, tree shaking et code splitting forment une meme boucle d’exploitation pour garder une application rapide lorsqu’elle gagne du trafic et du revenu.
PDF gratuit: cheatsheet Claude Code
Saisissez votre email et téléchargez une page avec commandes, habitudes de review et workflow sûr.
Nous protégeons vos données et n'envoyons pas de spam.
À propos de l'auteur
Masa
Ingénieur spécialisé dans les workflows pratiques avec Claude Code.
Articles liés
Permission receipt Claude Code : portée, preuves et rollback
Modèle de permission receipt pour Claude Code : actions autorisées, limites d'approbation, commandes de preuve, rollback et CTAs revenus.
Agent Harness securise pour Claude Code et Codex : permissions, verification et rollback
Construisez un Agent Harness pratique pour Claude Code et Codex avec politiques, plan, verification et recuperation.
Sous-agents Claude Code : guide pratique pour déléguer sans perdre le contrôle
Guide pratique des sous-agents Claude Code pour répartir articles et code : règles, prompts, pièges et checklist.