Claude-skill-registry bundle-performance
Monitor JavaScript bundle size and execution performance. Use when tracking bundle size, identifying large chunks, or optimizing load performance.
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-performance" ~/.claude/skills/majiayu000-claude-skill-registry-bundle-performance && rm -rf "$T"
manifest:
skills/data/bundle-performance/SKILL.mdsource content
Bundle Performance
Monitor JavaScript bundle size and its impact on performance.
Why Bundle Size Matters
| Bundle Size | LCP Impact | INP Impact |
|---|---|---|
| <100KB | Minimal | Minimal |
| 100-300KB | Moderate | Noticeable |
| 300-500KB | Significant | Degraded |
| >500KB | Severe | Poor |
Performance Budgets
| Metric | Good | Warning | Critical |
|---|---|---|---|
| Initial JS | <200KB | <500KB | >500KB |
| Per-route chunk | <100KB | <200KB | >200KB |
| Total JS | <500KB | <1MB | >1MB |
| First Load | <3s on 3G | <5s | >5s |
Build-Time Analysis
Vite
// vite.config.ts import { visualizer } from 'rollup-plugin-visualizer'; export default defineConfig({ build: { rollupOptions: { output: { manualChunks: { vendor: ['react', 'react-dom'], utils: ['lodash', 'date-fns'], }, }, }, }, plugins: [ visualizer({ filename: 'dist/stats.html', gzipSize: true, brotliSize: true, }), ], });
Webpack (Next.js)
// next.config.js const withBundleAnalyzer = require('@next/bundle-analyzer')({ enabled: process.env.ANALYZE === 'true', }); module.exports = withBundleAnalyzer({ // your config }); // Run: ANALYZE=true npm run build
Runtime Monitoring
Resource Timing API
function trackBundleLoading() { const observer = new PerformanceObserver((list) => { for (const entry of list.getEntries()) { if (entry.name.endsWith('.js')) { trackResourceLoad({ name: new URL(entry.name).pathname, size_bytes: (entry as PerformanceResourceTiming).transferSize, duration_ms: entry.duration, type: 'javascript', }); } } }); observer.observe({ type: 'resource', buffered: true }); }
Long Tasks API
function trackLongTasks() { const observer = new PerformanceObserver((list) => { for (const entry of list.getEntries()) { trackLongTask({ duration_ms: entry.duration, start_time_ms: entry.startTime, // Attribution for debugging name: (entry as any).attribution?.[0]?.name || 'unknown', container_type: (entry as any).attribution?.[0]?.containerType, }); // Alert on very long tasks if (entry.duration > 100) { captureMessage('Long task detected', { level: 'warning', extra: { duration_ms: entry.duration, route: window.location.pathname, }, }); } } }); observer.observe({ type: 'longtask', buffered: true }); }
Dynamic Import Tracking
// Track lazy-loaded chunks async function trackedImport<T>( importFn: () => Promise<T>, chunkName: string ): Promise<T> { const startTime = performance.now(); try { const module = await importFn(); const duration = performance.now() - startTime; trackChunkLoad({ chunk_name: chunkName, duration_ms: duration, success: true, }); return module; } catch (error) { trackChunkLoad({ chunk_name: chunkName, success: false, error_type: error instanceof Error ? error.name : 'unknown', }); throw error; } } // Usage const HeavyComponent = lazy(() => trackedImport( () => import('./HeavyComponent'), 'HeavyComponent' ) );
CI/CD Integration
Size Limit
// package.json { "size-limit": [ { "path": "dist/**/*.js", "limit": "200 KB" }, { "path": "dist/vendor*.js", "limit": "100 KB" } ] }
bundlewatch
// bundlewatch.config.json { "files": [ { "path": "./dist/main*.js", "maxSize": "150kB" }, { "path": "./dist/vendor*.js", "maxSize": "100kB" } ], "ci": { "trackBranches": ["main"], "repoBranchBase": "main" } }
Third-Party Script Tracking
function trackThirdPartyScripts() { const entries = performance.getEntriesByType('resource') as PerformanceResourceTiming[]; const thirdParty = entries.filter((entry) => { const url = new URL(entry.name); return url.hostname !== window.location.hostname; }); const summary = { count: thirdParty.length, total_size_bytes: thirdParty.reduce((sum, e) => sum + e.transferSize, 0), total_duration_ms: thirdParty.reduce((sum, e) => sum + e.duration, 0), scripts: thirdParty.map((e) => ({ url: e.name, size_bytes: e.transferSize, duration_ms: e.duration, })), }; trackThirdPartyImpact(summary); }
Optimization Strategies
| Strategy | Impact | Implementation |
|---|---|---|
| Code splitting | High | Route-based chunks |
| Tree shaking | High | ES modules, sideEffects |
| Dynamic imports | High | Lazy load non-critical |
| Compression | High | Brotli/gzip |
| Modern/legacy | Medium | module/nomodule |
| Vendor chunking | Medium | Manual chunks |
| Preload critical | Medium | modulepreload |
Anti-Patterns
- Loading entire SDK in main bundle
- Not code-splitting routes
- Importing entire lodash/moment
- Missing tree-shaking (CommonJS)
- Not monitoring bundle size in CI
- Third-party scripts without budget
Related Skills
- See
for LCP/INP impactskills/core-web-vitals - See
for JS impact on hydrationskills/hydration-performance - See
for lab testingskills/synthetic-monitoring
References
- Performance budgetsreferences/performance.md
- Framework-specific optimizationreferences/frameworks/*.md