# Performance budget defined for JS bundle size, CSS, images, LCP, FID, and CLS

- **Pattern:** `ab-002020` (`performance-core.script-style-efficiency.performance-budget`)
- **Severity:** info
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-002020
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-002020)

## Why it matters

Without a performance budget enforced in CI, bundle size, LCP, and CLS regressions go undetected until users report slowness (ISO-25010 capacity). A JavaScript bundle that grew from 150 KB to 500 KB over six months — one dependency upgrade at a time — produces no build error and no alert. Performance budgets create an automated gate: the build fails when the bundle exceeds the limit, turning performance regression into a first-class CI failure alongside type errors and test failures. Without this gate, performance optimization is reactive rather than preventive.

## Severity rationale

Info because missing performance budgets allow regressions to ship silently over time, but the immediate impact is potential rather than confirmed — a process gap rather than a current defect.

## Remediation

Define and enforce performance budgets in your build pipeline using `size-limit`:

```json
// package.json
{
  "scripts": {
    "size": "size-limit"
  },
  "size-limit": [
    { "name": "main bundle", "path": ".next/static/chunks/main-*.js", "limit": "200 KB" },
    { "name": "styles",      "path": ".next/static/css/**.css",        "limit": "50 KB" }
  ]
}
```

Add to CI (`.github/workflows/ci.yml`):
```yaml
- name: Check bundle sizes
  run: npm run size
```

For Core Web Vitals budgets, add Lighthouse CI:
```yaml
- name: Lighthouse CI
  run: lhci autorun
  env:
    LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
```

Set initial budget limits from your current measured baselines — then tighten by 10% each quarter. The goal is regression prevention, not aspirational targets that immediately fail every build.

## Detection

- **ID:** `performance-budget`
- **Severity:** `info`
- **What to look for:** Count all relevant instances and enumerate each. Check for performance budget configuration in build tooling (webpack, Vite, Next.js). Look for size limits on bundles, CSS, images in `package.json`, `next.config.ts`, or separate config files. Check whether CI/CD fails if budgets are exceeded.
- **Pass criteria:** Performance budgets are defined for key metrics: JS bundle size (gzipped), CSS bundle size, image count/size, LCP target, FID/INP target, CLS target. Build process validates against budgets and fails if exceeded.
- **Fail criteria:** No performance budget defined, or budgets exist but are not enforced. Build does not fail if metrics exceed budgets.
- **Skip (N/A) when:** The project is very small (single page, minimal JS) and budget enforcement is overkill.
- **Detail on fail:** Describe the missing budget. Example: `"No performance budget configured. JS bundle grew to 500KB gzipped unnoticed; no CI check would catch regressions"` or `"Budget mentioned in docs but not enforced in build; developers unaware when they exceed it"`.
- **Remediation:** Define and enforce performance budgets:

  With webpack-bundle-analyzer:
  ```ts
  // webpack.config.js
  const webpackBundleAnalyzer = require('webpack-bundle-analyzer')
  module.exports = {
    plugins: [
      new webpackBundleAnalyzer.BundleAnalyzerPlugin({
        analyzerMode: 'static',
        maxSize: 250000  // 250KB gzipped budget
      })
    ]
  }
  ```

  With Vite:
  ```ts
  // vite.config.ts
  import { defineConfig } from 'vite'
  export default defineConfig({
    build: {
      rollupOptions: {
        output: {
          // Configure code splitting and monitor sizes
        }
      }
    }
  })
  ```

  With Next.js:
  ```json
  {
    "scripts": {
      "size": "next build && size-limit"
    },
    "size-limit": [
      { "name": "app.js", "path": ".next/static/chunks/main.js", "limit": "200KB" },
      { "name": "styles.css", "path": ".next/static/css/**.css", "limit": "50KB" }
    ]
  }
  ```

---

## External references

- iso-25010 performance-efficiency.capacity

Taxons: observability, performance

HTML version: https://auditbuffet.com/patterns/ab-002020
