install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/bundle-optimizer" ~/.claude/skills/majiayu000-claude-skill-registry-bundle-optimizer && rm -rf "$T"
manifest:
skills/data/bundle-optimizer/SKILL.mdsource content
Bundle Optimizer
You are an expert in optimizing JavaScript bundle sizes and build performance for the emotive-mascot platform.
When to Use This Skill
- Bundle size exceeds targets (> 250 KB gzipped)
- Slow initial page load times
- Implementing code splitting
- Analyzing dependency composition
- Tree-shaking optimization
- Progressive loading implementation
Current Bundle Targets
{ "emotive-mascot.umd.js": { "uncompressed": "< 900 KB", "gzipped": "< 234 KB" }, "emotive-mascot.minimal.js": { "uncompressed": "< 400 KB", "gzipped": "< 120 KB" }, "emotive-mascot.audio.js": { "uncompressed": "< 700 KB", "gzipped": "< 200 KB" } }
Analysis Tools
Check Current Size
# Build and check sizes npm run build # View bundle sizes ls -lh dist/ # Check gzipped sizes gzip -c dist/emotive-mascot.umd.js | wc -c
Analyze Bundle Composition
# Generate visual analysis npm run build:analyze # This creates bundle-analysis.html showing: # - Module sizes # - Duplicate dependencies # - Large imports
NPM Package Analysis
# Audit dependencies npm audit # Check for unused dependencies npx depcheck # Analyze package sizes npx bundle-phobia <package-name>
Optimization Techniques
1. Code Splitting
Split large features into separate chunks:
// Instead of direct import import { AudioEngine } from '@joshtol/emotive-engine'; // Use dynamic import const loadAudio = async () => { const { AudioEngine } = await import('@joshtol/emotive-engine/audio'); return new AudioEngine(); };
2. Tree Shaking
Ensure dead code elimination works:
// rollup.config.js export default { treeshake: { moduleSideEffects: false, propertyReadSideEffects: false, unknownGlobalSideEffects: false, }, }; // Use named imports (not default) import { EmotiveMascot, emotions } from '@joshtol/emotive-engine'; // NOT: import EmotiveEngine from '@joshtol/emotive-engine'
3. Minification
Optimize Terser settings:
// rollup.config.js import terser from '@rollup/plugin-terser'; terser({ compress: { drop_console: true, drop_debugger: true, pure_funcs: ['console.log', 'console.debug'], passes: 2, // Multiple passes for better compression }, mangle: { properties: { regex: /^_/, // Mangle private properties starting with _ }, }, format: { comments: false, // Remove all comments }, });
4. Remove Unused Dependencies
# Find what can be removed npx depcheck # Uninstall unused packages npm uninstall <package-name>
Progressive Loading Strategy
Minimal Initial Bundle
Create a minimal bundle for fast first paint:
// emotive-mascot.minimal.js includes ONLY: // - Core engine // - Basic emotions (5 most common) // - Essential physics // Total: ~120 KB gzipped
Lazy Load Features
Load features as needed:
// Load full emotion set on demand const loadFullEmotions = async () => { const { extendedEmotions } = await import( '@joshtol/emotive-engine/emotions/extended' ); mascot.addEmotions(extendedEmotions); }; // Load audio module only when needed const enableAudio = async () => { const { AudioEngine } = await import('@joshtol/emotive-engine/audio'); mascot.enableAudio(new AudioEngine()); }; // Load LLM plugin for chat features const enableChat = async () => { const { LLMEmotionPlugin } = await import( '@joshtol/emotive-engine/plugins/llm' ); mascot.addPlugin(new LLMEmotionPlugin()); };
Build Configuration
Rollup Config Optimization
// rollup.config.js import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; import terser from '@rollup/plugin-terser'; export default { input: 'src/index.js', output: { file: 'dist/emotive-mascot.umd.js', format: 'umd', name: 'EmotiveMascot', sourcemap: false, // Disable in production }, plugins: [ resolve({ browser: true, preferBuiltins: false, }), commonjs(), terser({ compress: { drop_console: true, passes: 2, }, }), ], treeshake: { moduleSideEffects: false, }, };
Next.js Config Optimization
// next.config.js module.exports = { swcMinify: true, // Use SWC for faster minification webpack: (config, { isServer }) => { if (!isServer) { // Bundle analyzer if (process.env.ANALYZE === 'true') { const { BundleAnalyzerPlugin, } = require('webpack-bundle-analyzer'); config.plugins.push( new BundleAnalyzerPlugin({ analyzerMode: 'static', openAnalyzer: true, }) ); } // Optimize chunks config.optimization.splitChunks = { chunks: 'all', cacheGroups: { default: false, vendors: false, // Separate emotive-mascot into its own chunk emotive: { name: 'emotive-mascot', test: /[\\/]node_modules[\\/]@joshtol[\\/]emotive-engine/, priority: 40, }, }, }; } return config; }, };
Monitoring Bundle Size
Package.json Configuration
{ "bundlesize": [ { "path": "./dist/emotive-mascot.umd.js", "maxSize": "900 KB", "compression": "none" }, { "path": "./dist/emotive-mascot.umd.js", "maxSize": "250 KB", "compression": "gzip" } ], "scripts": { "size": "bundlesize", "build:check": "npm run build && npm run size" } }
CI/CD Integration
# .github/workflows/bundle-size.yml name: Bundle Size Check on: [pull_request] jobs: check-size: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - run: npm ci - run: npm run build - run: npm run size
Quick Wins Checklist
- Remove unused dependencies (run
)npx depcheck - Enable tree-shaking in build config
- Use terser with aggressive settings
- Remove console.logs in production
- Disable sourcemaps in production
- Use dynamic imports for large features
- Compress images and assets
- Remove duplicate dependencies
- Use minimal build for simple use cases
- Monitor bundle size in CI/CD
Common Issues
Issue: Bundle size suddenly increased Solution: Run
npm run build:analyze to identify what changed
Issue: Tree-shaking not working Solution: Ensure all imports are named (not default) and check
sideEffects: false in package.json
Issue: Dependencies duplicated Solution: Check npm/yarn lock file, use
npm dedupe
Issue: Slow build times Solution: Enable caching, use
esbuild or swc
instead of Babel