bundle-optimization
Bundle analysis and optimization strategies for JavaScript applications.
$ npx -y skills add notque/vexjoy-agent --agent claude-codeHow it fires
How this agent gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
Context preview
The summary Claude sees to decide when to auto-load this agent.
Bundle analysis and optimization strategies for JavaScript applications.
Agent definition
bundle-optimization.mdBundle Optimization
Bundle analysis and optimization strategies for JavaScript applications.
Bundle Size Targets
| Application Type | Initial JS | Initial CSS | Images | Total | |------------------|-----------|-------------|--------|-------| | Marketing Site | <150KB | <50KB | <500KB | <700KB | | E-commerce | <250KB | <75KB | <800KB | <1.1MB | | SaaS Dashboard | <400KB | <100KB | <300KB | <800KB | | Content Site | <200KB | <60KB | <600KB | <860KB |
Bundle Analysis Workflow
# 1. Build with stats
npm run build -- --profile --json > stats.json
# 2. Analyze bundle
npx webpack-bundle-analyzer stats.json
# 3. Check for duplicates
npx webpack-bundle-analyzer stats.json --mode static
# 4. Generate report
webpack-bundle-analyzer stats.json --mode json --report bundle-report.json
Common Bundle Problems
1. Large Dependencies
**Problem**: Single library taking >100KB
**Detection**:
npx webpack-bundle-analyzer build/stats.json
# Look for packages >100KB in treemap
**Solutions**:
- Replace with smaller alternative
- Use tree-shakeable ES modules version
- Lazy load if not critical
- Import specific functions only
**Example**:
// BAD: Import entire library (300KB)
import _ from 'lodash'
const result = _.uniq(array)
// GOOD: Import specific function (5KB)
import uniq from 'lodash/uniq'
const result = uniq(array)
// BETTER: Use native alternative (0KB)
const result = [...new Set(array)]
2. Duplicate Modules
**Problem**: Same module bundled multiple times
**Detection**:
npx webpack-bundle-analyzer build/stats.json
# Look for duplicate package names at different paths
**Solutions**:
- Configure webpack `resolve.alias`
- Update dependencies to use same version
- Use `splitChunks` optimization
**Example**:
// webpack.config.js
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
priority: 10
}
}
}
},
resolve: {
alias: {
// Force single version
'react': path.resolve(__dirname, 'node_modules/react')
}
}
}3. Unused Code
**Problem**: Dead code included in bundle
**Detection**:
# Check tree-shaking
npx webpack --mode production --analyze
# Check coverage in Chrome DevTools
# Coverage tab -> Record -> Reload
**Solutions**:
- Enable tree-shaking (use ES modules)
- Remove unused imports
- Use dynamic imports for code not needed initially
- Configure sideEffects in package.json
**Example**:
// package.json
{
"sideEffects": false // Enable tree-shaking
}// BAD: Import entire module
import * as utils from './utils'
// GOOD: Import only what's needed
import { formatDate, formatCurrency } from './utils'4. No Code Splitting
**Problem**: Everything in one bundle, slow initial load
**Solutions**:
// Route-based code splitting
const ProductPage = lazy(() => import('./pages/ProductPage'))
const CartPage = lazy(() => import('./pages/CartPage'))
// Component-based code splitting (for large components)
const HeavyChart = lazy(() => import('./components/HeavyChart'))
// Feature-based code splitting
const AdminPanel = lazy(() => import('./features/admin'))Optimization Strategies
1. Code Splitting Configuration
// next.config.js
module.exports = {
webpack: (config) => {
config.optimization.splitChunks = {
chunks: 'all',
cacheGroups: {
default: false,
vendors: false,
// Vendor chunk
vendor: {
name: 'vendor',
chunks: 'all',
test: /node_modules/,
priority: 20
},
// Common chunk
common: {
name: 'common',
minChunks: 2,
chunks: 'all',
priority: 10,
reuseExistingChunk: true,
enforce: true
}
}
}
return config
}
}2. Dynamic Imports
// Lazy load heavy libraries
async function generatePDF() {
const { jsPDF } = await import('jspdf')
const doc = new jsPDF()
// Generate PDF
}
// Lazy load by condition
if (user.isAdmin) {
const { AdminTools } = await import('./AdminTools')
renderAdminTools(AdminTools)
}
// Lazy load on interaction
button.addEventListener('click', async () => {
const { showModal } = await import('./modal')
showModal()
})3. Tree Shaking
// Enable in package.json
{
"sideEffects": [
"*.css",
"*.scss"
]
}
// Use named exports (tree-shakeable)
export function utilA() {}
export function utilB() {}
// Don't use default export of object (not tree-shakeable)
// BAD:
export default {
utilA,
utilB
}4. Bundle Analysis Report
interface BundleAnalysis {
totalSize: number
gzippedSize: number
chunks: BundleChunk[]
dependencies: DependencyInfo[]
duplicates: DuplicateModule[]
}
interface BundleChunk {
name: string
size: number
files: string[]
isInitial: boolean
isAsync: boolean
}
interface DependencyInfo {
name: string
version: string
size: number
isTreeShakeable: boolean
}
interface DuplicateModule {
name: string
instances: number
totalWastedSize: number
}
function analyzeBundleSize(statsPath: string): BundleAnalysis {
const stats = require(statsPath)
const chunks = stats.chunks.map(chunk => ({
name: chunk.names[0] || chunk.id,
size: chunk.size,
files: chunk.files,
isInitial: chunk.initial,
isAsync: !chunk.initial
}))
const dependencies = analyzeDependencies(stats.modules)
const duplicates = findDuplicateModules(stats.modules)
return {
totalSize: stats.assets.reduce((sum, asset) => sum + asset.size, 0),
gzippedSize: estimateGzippedSize(stats.assets),
chunks,
dependencies,
duplicates
}
}Before/After Validation
Always include before/after metr
Read more
Bundle Optimization
Bundle analysis and optimization strategies for JavaScript applications.
Bundle Size Targets
| Application Type | Initial JS | Initial CSS | Images | Total | |------------------|-----------|-------------|--------|-------| | Marketing Site | <150KB | <50KB | <500KB | <700KB | | E-commerce | <250KB | <75KB | <800KB | <1.1MB | | SaaS Dashboard | <400KB | <100KB | <300KB | <800KB | | Content Site | <200KB | <60KB | <600KB | <860KB |
Bundle Analysis Workflow
# 1. Build with stats npm run build -- --profile --json > stats.json # 2. Analyze bundle npx webpack-bundle-analyzer stats.json # 3. Check for duplicates npx webpack-bundle-analyzer stats.json --mode static # 4. Generate report webpack-bundle-analyzer stats.json --mode json --report bundle-report.json
Common Bundle Problems
1. Large Dependencies
**Problem**: Single library taking >100KB
**Detection**:
npx webpack-bundle-analyzer build/stats.json # Look for packages >100KB in treemap
**Solutions**:
- Replace with smaller alternative
- Use tree-shakeable ES modules version
- Lazy load if not critical
- Import specific functions only
**Example**:
// BAD: Import entire library (300KB) import _ from 'lodash' const result = _.uniq(array) // GOOD: Import specific function (5KB) import uniq from 'lodash/uniq' const result = uniq(array) // BETTER: Use native alternative (0KB) const result = [...new Set(array)]
2. Duplicate Modules
**Problem**: Same module bundled multiple times
**Detection**:
npx webpack-bundle-analyzer build/stats.json # Look for duplicate package names at different paths
**Solutions**:
- Configure webpack `resolve.alias`
- Update dependencies to use same version
- Use `splitChunks` optimization
**Example**:
// webpack.config.js
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
priority: 10
}
}
}
},
resolve: {
alias: {
// Force single version
'react': path.resolve(__dirname, 'node_modules/react')
}
}
}3. Unused Code
**Problem**: Dead code included in bundle
**Detection**:
# Check tree-shaking npx webpack --mode production --analyze # Check coverage in Chrome DevTools # Coverage tab -> Record -> Reload
**Solutions**:
- Enable tree-shaking (use ES modules)
- Remove unused imports
- Use dynamic imports for code not needed initially
- Configure sideEffects in package.json
**Example**:
// package.json
{
"sideEffects": false // Enable tree-shaking
}// BAD: Import entire module
import * as utils from './utils'
// GOOD: Import only what's needed
import { formatDate, formatCurrency } from './utils'4. No Code Splitting
**Problem**: Everything in one bundle, slow initial load
**Solutions**:
// Route-based code splitting
const ProductPage = lazy(() => import('./pages/ProductPage'))
const CartPage = lazy(() => import('./pages/CartPage'))
// Component-based code splitting (for large components)
const HeavyChart = lazy(() => import('./components/HeavyChart'))
// Feature-based code splitting
const AdminPanel = lazy(() => import('./features/admin'))Optimization Strategies
1. Code Splitting Configuration
// next.config.js
module.exports = {
webpack: (config) => {
config.optimization.splitChunks = {
chunks: 'all',
cacheGroups: {
default: false,
vendors: false,
// Vendor chunk
vendor: {
name: 'vendor',
chunks: 'all',
test: /node_modules/,
priority: 20
},
// Common chunk
common: {
name: 'common',
minChunks: 2,
chunks: 'all',
priority: 10,
reuseExistingChunk: true,
enforce: true
}
}
}
return config
}
}2. Dynamic Imports
// Lazy load heavy libraries
async function generatePDF() {
const { jsPDF } = await import('jspdf')
const doc = new jsPDF()
// Generate PDF
}
// Lazy load by condition
if (user.isAdmin) {
const { AdminTools } = await import('./AdminTools')
renderAdminTools(AdminTools)
}
// Lazy load on interaction
button.addEventListener('click', async () => {
const { showModal } = await import('./modal')
showModal()
})3. Tree Shaking
// Enable in package.json
{
"sideEffects": [
"*.css",
"*.scss"
]
}
// Use named exports (tree-shakeable)
export function utilA() {}
export function utilB() {}
// Don't use default export of object (not tree-shakeable)
// BAD:
export default {
utilA,
utilB
}4. Bundle Analysis Report
interface BundleAnalysis {
totalSize: number
gzippedSize: number
chunks: BundleChunk[]
dependencies: DependencyInfo[]
duplicates: DuplicateModule[]
}
interface BundleChunk {
name: string
size: number
files: string[]
isInitial: boolean
isAsync: boolean
}
interface DependencyInfo {
name: string
version: string
size: number
isTreeShakeable: boolean
}
interface DuplicateModule {
name: string
instances: number
totalWastedSize: number
}
function analyzeBundleSize(statsPath: string): BundleAnalysis {
const stats = require(statsPath)
const chunks = stats.chunks.map(chunk => ({
name: chunk.names[0] || chunk.id,
size: chunk.size,
files: chunk.files,
isInitial: chunk.initial,
isAsync: !chunk.initial
}))
const dependencies = analyzeDependencies(stats.modules)
const duplicates = findDuplicateModules(stats.modules)
return {
totalSize: stats.assets.reduce((sum, asset) => sum + asset.size, 0),
gzippedSize: estimateGzippedSize(stats.assets),
chunks,
dependencies,
duplicates
}
}Before/After Validation
Always include before/after metr
Essays and writing behind this toolkit live at vexjoy.com. AI agents skip steps. "Looks correct" replaces running tests. "Trivial change" replaces verification.
Repo: notque/vexjoy-agent
Other agents on vexjoy-agent.
- ansible-automation-engineer
Ansible automation: playbooks, roles, collections, Molecule testing, Vault security.
Open agent - modules
**Scope**: Module selection patterns, builtin vs command/shell decisions, collection modules, and version-specific module changes **Version range**: ansible-core 2.14+ / Ansible Collections (community.general 7.0+) **Generated**: 2026-04-04 — verify against current Ansible
Open agent - testing
**Scope**: Molecule test scenarios, ansible-lint rules, idempotency validation, and check-mode patterns **Version range**: Molecule 6.0+ / ansible-lint 6.0+ / ansible-core 2.14+ **Generated**: 2026-04-04 — verify against current Molecule and ansible-lint documentation
Open agent - base-instructions
Universal operational rules injected by /do at agent dispatch. Domain-specific rules live in each agent's .md file.
Open agent - communication-patterns
**Scope**: Failure modes in agent output style — over-reporting, self-congratulation, verbose narration, and hedging. Covers what to detect and how to fix each. **Version range**: all versions **Generated**: 2026-05-11
Open agent - combat-effects-upgrade
Zero-dependency combat visual upgrades: CSS particle replacement, Framer Motion combat juice, CSS 3D card transforms.
Open agent

