perf-budget-enforcement
Paste into Claude Code, Claude.ai, the desktop app, or the browser extension — ⌘/Ctrl+V. ✓ Copied. Switch to Claude and paste — ⌘/Ctrl+V.
Performance Budget Enforcement
Wire Lighthouse CI and bundle-size checks into the project's CI pipeline so that performance regressions are caught at the PR stage, not in production.
Usage
/perf-budget-enforcement <project-root> [--ci github|ado] [--format lhci|bundlesize|both] [--target-score <0-100>]
Examples:
/perf-budget-enforcement . --ci github --format both— full setup for GitHub Actions/perf-budget-enforcement . --ci ado --format lhci— Azure DevOps YAML task/perf-budget-enforcement . --format bundlesize— bundle-size budget only
Phase 1 — Inventory Existing Configuration
Read the project root to understand what already exists:
ls -la .github/workflows/ 2>/dev/null
ls -la .lighthouserc* lighthouserc.* 2>/dev/null
cat package.json | node -e "
const p = JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));
console.log('scripts:', JSON.stringify(p.scripts, null, 2));
console.log('devDeps:', JSON.stringify(p.devDependencies, null, 2));
"
Detect:
- CI system (GitHub Actions, Azure DevOps, or none)
- Framework (Next.js, Vite, Webpack, .NET)
- Existing performance tooling
Phase 2 — Generate Lighthouse CI Configuration
Create .lighthouserc.json (or lighthouserc.js for dynamic config):
{
"ci": {
"collect": {
"numberOfRuns": 3,
"startServerCommand": "npm start",
"startServerReadyPattern": "ready on|listening on|started on",
"startServerReadyTimeout": 30000,
"url": [
"http://localhost:3000",
"http://localhost:3000/products",
"http://localhost:3000/about"
],
"settings": {
"formFactor": "mobile",
"throttlingMethod": "simulate",
"screenEmulation": {
"mobile": true,
"width": 412,
"height": 823,
"deviceScaleFactor": 1.75,
"disabled": false
}
}
},
"assert": {
"preset": "lighthouse:no-pwa",
"assertions": {
"categories:performance": ["error", { "minScore": 0.9 }],
"largest-contentful-paint": ["error", { "maxNumericValue": 2500 }],
"interaction-to-next-paint": ["warn", { "maxNumericValue": 200 }],
"cumulative-layout-shift": ["error", { "maxNumericValue": 0.1 }],
"first-contentful-paint": ["warn", { "maxNumericValue": 1800 }],
"total-blocking-time": ["warn", { "maxNumericValue": 300 }],
"server-response-time": ["warn", { "maxNumericValue": 600 }],
"render-blocking-resources": ["warn", { "maxLength": 0 }],
"unused-javascript": ["warn", { "maxNumericValue": 0 }],
"uses-optimized-images": ["warn", { "maxLength": 0 }],
"uses-webp-images": ["warn", { "maxLength": 0 }]
}
},
"upload": {
"target": "temporary-public-storage"
}
}
}
Threshold guidance:
- Use
"error"for hard blockers (fail the PR): LCP, CLS, overall score - Use
"warn"for soft warnings (notify but don't block): FCP, TBT, individual audits temporary-public-storage: stores reports publicly for 7 days (no auth needed). For private repos, use LHCI server or"no-upload".
Phase 3 — GitHub Actions Workflow
Create .github/workflows/lighthouse-ci.yml:
name: Performance Audit (Lighthouse CI)
on:
pull_request:
branches: [main, develop]
push:
branches: [main]
jobs:
lighthouse:
name: Lighthouse CI
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
env:
NODE_ENV: production
- name: Run Lighthouse CI
run: npx lhci autorun
env:
LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
- name: Upload Lighthouse Reports
if: always()
uses: actions/upload-artifact@v4
with:
name: lighthouse-reports
path: .lighthouseci/
retention-days: 14
For Next.js projects, replace the Build step with:
- name: Build Next.js
run: npx next build
env:
NEXT_TELEMETRY_DISABLED: 1
- name: Start Next.js server
run: npx next start &
env:
PORT: 3000
Phase 4 — Azure DevOps Pipeline Task
For projects using Azure DevOps instead of GitHub Actions, create an equivalent stage
in azure-pipelines.yml:
- stage: PerformanceAudit
displayName: 'Performance Audit (Lighthouse CI)'
dependsOn: Build
condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest'))
jobs:
- job: LighthouseCI
displayName: 'Run Lighthouse CI'
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
inputs:
versionSpec: '20.x'
- script: npm ci
displayName: 'Install dependencies'
- script: npm run build
displayName: 'Build'
env:
NODE_ENV: production
- script: npx lhci autorun
displayName: 'Run Lighthouse CI'
continueOnError: false
- task: PublishPipelineArtifact@1
displayName: 'Upload Lighthouse Reports'
condition: always()
inputs:
targetPath: '$(System.DefaultWorkingDirectory)/.lighthouseci'
artifact: 'lighthouse-reports'
Phase 5 — Bundle Size Budget (JavaScript)
Using bundlesize
Add to package.json:
{
"bundlesize": [
{
"path": "./dist/static/js/*.js",
"maxSize": "200 kB",
"compression": "gzip"
},
{
"path": "./dist/static/css/*.css",
"maxSize": "50 kB",
"compression": "gzip"
}
]
}
Add to CI:
npx bundlesize
Using size-limit (preferred for Next.js / React projects)
Install: npm install --save-dev @size-limit/preset-app
Add to package.json:
{
"size-limit": [
{
"path": ".next/static/chunks/pages/index-*.js",
"limit": "75 KB"
},
{
"path": ".next/static/chunks/framework-*.js",
"limit": "45 KB"
}
],
"scripts": {
"size": "size-limit",
"analyze": "size-limit --why"
}
}
Add npm run size to the CI workflow after build.
Phase 6 — Recommended Budget Values
Adapt these to project requirements:
| Budget | Conservative (existing site) | Ambitious (new build) | Green-field best-practice |
|---|---|---|---|
| Performance score | ≥ 75 | ≥ 85 | ≥ 90 |
| LCP | ≤ 3.5 s | ≤ 2.5 s | ≤ 1.8 s |
| INP | ≤ 400 ms | ≤ 200 ms | ≤ 150 ms |
| CLS | ≤ 0.15 | ≤ 0.1 | ≤ 0.05 |
| JS bundle (gzip) | ≤ 400 KB | ≤ 200 KB | ≤ 100 KB |
| Total page weight | ≤ 3 MB | ≤ 1.5 MB | ≤ 800 KB |
Phase 7 — Verification Checklist
After generating all files, verify:
-
.lighthouserc.jsonasserts at least LCP, CLS, and performance score - CI workflow runs on pull_request events (not just push)
-
numberOfRuns: 3to reduce variance - Appropriate
startServerCommandset for the project type - Bundle budget covers at least the main JS chunk
- Azure DevOps pipeline has
continueOnError: falseso failures block the PR -
LHCI_GITHUB_APP_TOKENdocumented in the project's CI secrets setup guide
Reference files
reference.md— LHCI assertion syntax, assertion levels, and audit ID listtemplates.md— ready-to-use config file templates for Next.js, Sitecore JSS, .NET MVC, Umbraco
Technical details
- Plugin
- performance-auditor
- Author
- Dakota Smith
- Skill name
perf-budget-enforcement- Maturity
- experimental
- Security review
- No security review
- Owners
-
- engineering
- Argument hint
<project-root> [--ci github|ado] [--format lhci|bundlesize|both] [--target-score <0-100>]- Allowed tools
-
ReadWriteGlobGrepBash(cat *)Bash(ls *)Bash(node *)WebFetch(domain:web.dev)WebFetch(domain:github.com)
- Source
plugins/performance-auditor/skills/perf-budget-enforcement/SKILL.md
Edit this skill on GitHub — opens GitHub's web editor. No git knowledge needed.