48 / 95 · 05 Performance & Chaos Engineering · Web Vitals Performance Gates in CI← prev⊞ allnext →☰ Read as one page
8.3Multi-Stage Performance Pipeline
For mature teams, performance validation should be a multi-stage process:
# .github/workflows/performance-gates.yml
name: Performance Gates
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
# Stage 1: Build-time checks (fast, every PR)
build-time-budget:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci && npm run build
- name: Check bundle sizes
run: npx bundlesize --config bundlesize.config.json
- name: Check for new dependencies > 50KB
run: |
npx webpack-bundle-analyzer dist/stats.json \
--mode json --no-open -r bundle-report.json
node scripts/check-large-deps.js bundle-report.json
# Stage 2: Lighthouse audit (medium speed, every PR)
lighthouse-audit:
needs: build-time-budget
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci && npm run build
- name: Start local server
run: npm run serve &
env:
PORT: 3000
- name: Wait for server
run: npx wait-on http://localhost:3000 --timeout 30000
- name: Run Lighthouse CI
uses: treosh/lighthouse-ci-action@v11
with:
urls: |
http://localhost:3000/
http://localhost:3000/products/1
configPath: ./lighthouserc.json
# Stage 3: API performance (on merge to main only)
api-performance:
if: github.event_name == 'push'
needs: [build-time-budget, lighthouse-audit]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run k6 API performance tests
uses: grafana/k6-action@v0.4.0
with:
filename: tests/performance/api-budget.js
flags: --out json=k6-results.json
env:
K6_TARGET_URL: ${{ secrets.STAGING_URL }}
- name: Validate k6 thresholds
run: |
# k6 exits non-zero if thresholds fail
echo "k6 thresholds validated successfully"
- name: Upload results
uses: actions/upload-artifact@v4
with:
name: k6-api-budget-results
path: k6-results.json