# Bundle Optimization

Strategies for reducing JavaScript bundle size.

## Analysis

```bash
# Analyze bundle composition
web-dev build --analyze --agent

# Check output sizes
ls -la dist/assets/*.js
```

## Code Splitting

### Dynamic Imports

```typescript
// Route-based splitting
const routes = {
  '/dashboard': () => import('./pages/dashboard'),
  '/settings': () => import('./pages/settings'),
};

// Load on demand
async function loadRoute(path: string) {
  const module = await routes[path]();
  return module.default;
}
```

### Component-level Splitting

```typescript
// Heavy component loaded on demand
class MyPage extends FASTElement {
  async loadChart() {
    const { ChartComponent } = await import('./chart-component');
    // Use component
  }
}
```

## Tree Shaking

```typescript
// ❌ Imports entire library
import _ from 'lodash';

// ✅ Imports only what's needed
import debounce from 'lodash/debounce';

// ✅ Named imports (if library supports)
import { debounce } from 'lodash-es';
```

## Dependency Audit

```bash
# Find large dependencies
npx source-map-explorer dist/assets/*.js

# Check bundle impact of a package
npx bundlephobia lodash
```

### Common Offenders

| Library | Size | Alternative |
|---------|------|-------------|
| moment.js | 300KB | date-fns (30KB) or dayjs (6KB) |
| lodash | 70KB | lodash-es with tree shaking |
| rxjs | 50KB | Import operators individually |

## Minification

Vite handles this automatically in production builds:

```typescript
// vite.config.ts
export default defineConfig({
  build: {
    minify: 'esbuild', // or 'terser' for more aggressive
    rollupOptions: {
      output: {
        manualChunks: {
          vendor: ['@microsoft/fast-element'],
        },
      },
    },
  },
});
```

## Compression

```typescript
// vite.config.ts
import viteCompression from 'vite-plugin-compression';

export default defineConfig({
  plugins: [
    viteCompression({ algorithm: 'gzip' }),
    viteCompression({ algorithm: 'brotliCompress', ext: '.br' }),
  ],
});
```

## Thresholds

| Asset | Good | Warning | Fail |
|-------|------|---------|------|
| Entry chunk (gzip) | < 100KB | 100-150KB | > 200KB |
| Total JS (gzip) | < 350KB | 350-450KB | > 500KB |
| Per lazy chunk | < 50KB | 50-75KB | > 100KB |
