| name | lighthouse-ci-integrator |
| description | Integrates Lighthouse CI for automated performance testing, Core Web Vitals tracking, and regression detection in CI/CD pipelines. Use when user asks to "setup Lighthouse CI", "add performance testing", "monitor Core Web Vitals", or "prevent performance regressions". |
| allowed-tools | Write, Read, Bash, Glob |
Lighthouse CI Integrator
Sets up Lighthouse CI to automatically test performance, accessibility, SEO, and best practices in your CI/CD pipeline with budget enforcement and trend tracking.
When to Use
- "Setup Lighthouse CI"
- "Add performance testing to CI/CD"
- "Monitor Core Web Vitals"
- "Prevent performance regressions"
- "Track Lighthouse scores"
- "Setup performance budgets"
Instructions
1. Install Lighthouse CI
npm install --save-dev @lhci/cli
# or
yarn add --dev @lhci/cli
2. Create Configuration File
lighthouserc.js:
module.exports = {
ci: {
collect: {
// URLs to test
url: [
'http://localhost:3000/',
'http://localhost:3000/about',
'http://localhost:3000/products',
],
// Number of runs per URL
numberOfRuns: 3,
// Start server before collecting
startServerCommand: 'npm run serve',
startServerReadyPattern: 'Server listening',
// Or use static directory
staticDistDir: './dist',
// Settings
settings: {
preset: 'desktop', // or 'mobile'
// Throttling
throttling: {
rttMs: 40,
throughputKbps: 10240,
cpuSlowdownMultiplier: 1,
},
// Screen emulation
screenEmulation: {
mobile: false,
width: 1350,
height: 940,
deviceScaleFactor: 1,
disabled: false,
},
},
},
upload: {
target: 'temporary-public-storage',
// Or use LHCI server
// target: 'lhci',
// serverBaseUrl: 'https://your-lhci-server.com',
// token: process.env.LHCI_TOKEN,
},
assert: {
preset: 'lighthouse:recommended',
assertions: {
// Performance
'categories:performance': ['error', { minScore: 0.9 }],
'first-contentful-paint': ['warn', { maxNumericValue: 2000 }],
'largest-contentful-paint': ['error', { maxNumericValue: 2500 }],
'cumulative-layout-shift': ['error', { maxNumericValue: 0.1 }],
'total-blocking-time': ['warn', { maxNumericValue: 300 }],
'speed-index': ['warn', { maxNumericValue: 3000 }],
'interactive': ['warn', { maxNumericValue: 3500 }],
// Accessibility
'categories:accessibility': ['error', { minScore: 0.95 }],
// Best Practices
'categories:best-practices': ['error', { minScore: 0.9 }],
// SEO
'categories:seo': ['warn', { minScore: 0.9 }],
// Resource budgets
'resource-summary:script:size': ['error', { maxNumericValue: 500000 }],
'resource-summary:stylesheet:size': ['warn', { maxNumericValue: 100000 }],
'resource-summary:image:size': ['warn', { maxNumericValue: 1000000 }],
'resource-summary:font:size': ['warn', { maxNumericValue: 100000 }],
'total-byte-weight': ['warn', { maxNumericValue: 2000000 }],
// Other metrics
'uses-http2': 'error',
'uses-webp-images': 'warn',
'offscreen-images': 'warn',
'unused-css-rules': 'warn',
'unused-javascript': 'warn',
'modern-image-formats': 'warn',
'uses-optimized-images': 'warn',
'uses-text-compression': 'error',
'uses-responsive-images': 'warn',
},
},
},
};
Mobile Configuration:
// lighthouserc.mobile.js
module.exports = {
ci: {
collect: {
url: ['http://localhost:3000/'],
numberOfRuns: 3,
settings: {
preset: 'mobile',
throttling: {
rttMs: 150,
throughputKbps: 1638,
cpuSlowdownMultiplier: 4,
},
screenEmulation: {
mobile: true,
width: 412,
height: 823,
deviceScaleFactor: 2.625,
disabled: false,
},
formFactor: 'mobile',
},
},
assert: {
assertions: {
'categories:performance': ['error', { minScore: 0.85 }],
'first-contentful-paint': ['error', { maxNumericValue: 2500 }],
'largest-contentful-paint': ['error', { maxNumericValue: 4000 }],
},
},
},
};
3. Add npm Scripts
package.json:
{
"scripts": {
"build": "next build",
"serve": "next start",
"lhci:collect": "lhci collect",
"lhci:assert": "lhci assert",
"lhci:upload": "lhci upload",
"lhci:autorun": "lhci autorun",
"lhci:mobile": "lhci autorun --config=lighthouserc.mobile.js",
"lhci:desktop": "lhci autorun --config=lighthouserc.js"
}
}
4. GitHub Actions Integration
.github/workflows/lighthouse-ci.yml:
name: Lighthouse CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
lighthouse:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build application
run: npm run build
- name: Run Lighthouse CI (Desktop)
run: npm run lhci:desktop
env:
LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
- name: Run Lighthouse CI (Mobile)
run: npm run lhci:mobile
env:
LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
- name: Upload Lighthouse results
uses: actions/upload-artifact@v3
if: always()
with:
name: lighthouse-results
path: .lighthouseci
With deployment preview (Vercel/Netlify):
name: Lighthouse CI with Preview
on:
pull_request:
branches: [main]
jobs:
lighthouse:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Wait for Vercel Preview
uses: patrickedqvist/wait-for-vercel-preview@v1.2.0
id: wait-for-vercel
with:
token: ${{ secrets.GITHUB_TOKEN }}
max_timeout: 300
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install Lighthouse CI
run: npm install -g @lhci/cli
- name: Run Lighthouse CI
run: |
lhci autorun --url=${{ steps.wait-for-vercel.outputs.url }}
env:
LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
5. GitLab CI Integration
.gitlab-ci.yml:
lighthouse:
stage: test
image: node:18
before_script:
- npm ci
script:
- npm run build
- npm run lhci:autorun
artifacts:
paths:
- .lighthouseci
expire_in: 1 week
only:
- merge_requests
- main
6. Setup LHCI Server (Optional)
Docker Compose for LHCI Server:
# docker-compose.lhci.yml
version: '3.8'
services:
lhci-server:
image: patrickhulce/lhci-server:latest
ports:
- '9001:9001'
environment:
LHCI_STORAGE_METHOD: sql
LHCI_STORAGE_SQL_DIALECT: postgres
LHCI_STORAGE_SQL_DATABASE: lighthouse
LHCI_STORAGE_SQL_USERNAME: postgres
LHCI_STORAGE_SQL_PASSWORD: postgres
LHCI_STORAGE_SQL_HOST: postgres
depends_on:
- postgres
postgres:
image: postgres:14
environment:
POSTGRES_DB: lighthouse
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
volumes:
- lhci-postgres-data:/var/lib/postgresql/data
volumes:
lhci-postgres-data:
Start server:
docker-compose -f docker-compose.lhci.yml up -d
Create project:
lhci wizard
# Follow prompts to create project and get token
7. Budget.json (Alternative Format)
budget.json:
[
{
"path": "/*",
"timings": [
{
"metric": "interactive",
"budget": 3500
},
{
"metric": "first-meaningful-paint",
"budget": 2000
}
],
"resourceSizes": [
{
"resourceType": "script",
"budget": 300
},
{
"resourceType": "image",
"budget": 500
},
{
"resourceType": "stylesheet",
"budget": 100
},
{
"resourceType": "font",
"budget": 100
},
{
"resourceType": "total",
"budget": 1000
}
],
"resourceCounts": [
{
"resourceType": "third-party",
"budget": 10
}
]
}
]
8. Custom Audits
custom-audit.js:
// custom-audit.js
class CustomAudit extends Lighthouse.Audit {
static get meta() {
return {
id: 'custom-performance-check',
title: 'Custom Performance Check',
failureTitle: 'Custom performance check failed',
description: 'Validates custom performance requirements',
requiredArtifacts: ['devtoolsLogs', 'traces'],
};
}
static audit(artifacts, context) {
// Custom audit logic
const score = 1; // 0-1
return {
score,
numericValue: 100,
displayValue: '100ms',
};
}
}
module.exports = CustomAudit;
Use in lighthouserc.js:
module.exports = {
ci: {
collect: {
settings: {
plugins: ['./custom-audit.js'],
},
},
},
};
9. PR Comments Integration
Comment on PR with results:
# .github/workflows/lighthouse-ci.yml
- name: Comment PR with results
uses: treosh/lighthouse-ci-action@v9
with:
urls: |
https://example.com
https://example.com/about
uploadArtifacts: true
temporaryPublicStorage: true
10. Monitoring and Alerts
Slack notifications:
# .github/workflows/lighthouse-ci.yml
- name: Notify Slack
if: failure()
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
text: 'Lighthouse CI failed! Performance regression detected.'
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
Email notifications:
- name: Send email notification
if: failure()
uses: dawidd6/action-send-mail@v3
with:
server_address: smtp.gmail.com
server_port: 465
username: ${{ secrets.EMAIL_USERNAME }}
password: ${{ secrets.EMAIL_PASSWORD }}
subject: Lighthouse CI Failed
body: Performance regression detected in ${{ github.repository }}
to: team@example.com
11. Generate Reports
HTML Report:
# Generate HTML report locally
lhci collect
lhci upload --target=filesystem --outputDir=./lighthouse-reports
# Open report
open ./lighthouse-reports/index.html
JSON Report:
// parse-lighthouse-results.js
const fs = require('fs');
const results = JSON.parse(fs.readFileSync('.lighthouseci/manifest.json'));
results.forEach(result => {
const report = JSON.parse(fs.readFileSync(result.jsonPath));
console.log('URL:', report.finalUrl);
console.log('Performance:', report.categories.performance.score * 100);
console.log('Accessibility:', report.categories.accessibility.score * 100);
console.log('Best Practices:', report.categories['best-practices'].score * 100);
console.log('SEO:', report.categories.seo.score * 100);
console.log('---');
});
12. Performance Budgets
Strict budgets:
assertions: {
// Core Web Vitals (strict)
'largest-contentful-paint': ['error', { maxNumericValue: 2500 }],
'cumulative-layout-shift': ['error', { maxNumericValue: 0.1 }],
'first-input-delay': ['error', { maxNumericValue: 100 }],
// Page weight
'total-byte-weight': ['error', { maxNumericValue: 1500000 }], // 1.5MB
'dom-size': ['warn', { maxNumericValue: 800 }],
// JavaScript
'bootup-time': ['warn', { maxNumericValue: 3500 }],
'mainthread-work-breakdown': ['warn', { maxNumericValue: 4000 }],
}
Best Practices
DO:
- Run Lighthouse CI on every PR
- Set realistic performance budgets
- Test both mobile and desktop
- Monitor trends over time
- Use temporary storage for PRs
- Setup LHCI server for history
- Test multiple pages
- Include authentication flows
DON'T:
- Set budgets too strict initially
- Only test homepage
- Ignore accessibility scores
- Skip mobile testing
- Test only in production
- Forget to warm up the server
- Ignore flaky metrics
Checklist
- Lighthouse CI installed
- Configuration file created
- Performance budgets set
- CI/CD integration added
- Multiple URLs configured
- Mobile + Desktop testing
- Assertions configured
- PR comments enabled
- Monitoring setup
- Team notified of new checks