home / skills / dexploarer / claudius-skills / lighthouse-ci-integrator

This skill automates performance testing and Core Web Vitals tracking with Lighthouse CI in CI/CD, enforcing budgets and surfacing trends.

npx playbooks add skill dexploarer/claudius-skills --skill lighthouse-ci-integrator

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
12.6 KB
---
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

```bash
npm install --save-dev @lhci/cli
# or
yarn add --dev @lhci/cli
```

### 2. Create Configuration File

**lighthouserc.js:**
```javascript
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:**
```javascript
// 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:**
```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:**
```yaml
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):**
```yaml
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/[email protected]
        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:**
```yaml
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:**
```yaml
# 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:**
```bash
docker-compose -f docker-compose.lhci.yml up -d
```

**Create project:**
```bash
lhci wizard
# Follow prompts to create project and get token
```

### 7. Budget.json (Alternative Format)

**budget.json:**
```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:**
```javascript
// 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:**
```javascript
module.exports = {
  ci: {
    collect: {
      settings: {
        plugins: ['./custom-audit.js'],
      },
    },
  },
};
```

### 9. PR Comments Integration

**Comment on PR with results:**
```yaml
# .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:**
```yaml
# .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:**
```yaml
- 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: [email protected]
```

### 11. Generate Reports

**HTML Report:**
```bash
# Generate HTML report locally
lhci collect
lhci upload --target=filesystem --outputDir=./lighthouse-reports

# Open report
open ./lighthouse-reports/index.html
```

**JSON Report:**
```javascript
// 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:**
```javascript
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

Overview

This skill integrates Lighthouse CI into your CI/CD pipeline to automate performance testing, Core Web Vitals tracking, and regression detection. It provisions configs, npm scripts, and CI workflow steps to run desktop and mobile audits, enforce budgets, and surface failures on PRs. Use it to get repeatable Lighthouse reports, trend history, and alerting for regressions.

How this skill works

The integration installs @lhci/cli, adds lighthouserc configuration (desktop and mobile), and wires lhci commands into npm scripts and CI jobs. It collects multiple runs per URL, asserts scores and metrics against configured budgets, uploads results (temporary storage or LHCI server), and can post PR comments or notifications on failures. Optional custom audits, a self-hosted LHCI server, and report generation are supported.

When to use it

  • When you want automated Lighthouse audits on every pull request or push
  • To track Core Web Vitals and enforce performance budgets over time
  • To prevent regressions by failing CI when assertions break
  • When you need both mobile and desktop performance coverage
  • To add PR comments, Slack/email alerts, or uploadable reports

Best practices

  • Run LHCI on every PR and on main to catch regressions early
  • Start with realistic budgets and tighten them as metrics stabilize
  • Test multiple pages and include authenticated flows where relevant
  • Use temporary-public-storage for PRs and an LHCI server for long-term history
  • Run separate mobile and desktop configs and collect multiple runs to reduce flakiness
  • Upload artifacts and enable CI notifications (Slack/email) for immediate visibility

Example use cases

  • Add lhci autorun to GitHub Actions to fail PRs that drop Performance or Core Web Vitals
  • Run desktop and mobile LHCI in GitLab CI with artifacts and one-week retention
  • Host an LHCI server via Docker Compose to keep historical trends and project tokens
  • Use lighthouserc asserts to enforce resource budgets (script, image, stylesheet sizes)
  • Create a script to parse .lighthouseci JSON results and produce team-friendly summaries

FAQ

Do I need a self-hosted LHCI server?

No. Use temporary-public-storage for PRs initially; add a self-hosted LHCI server when you need retained history and trend analysis.

How do I reduce flaky results?

Collect multiple runs per URL, run separate mobile/desktop configs, warm up the server, and use consistent throttling and emulation settings.

Can I add custom audits?

Yes. Implement a Lighthouse Audit plugin and reference it in lighthouserc plugins to include custom checks.