Agent Skills: Lighthouse CI Integrator

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".

UncategorizedID: Dexploarer/claudius-skills/lighthouse-ci-integrator

Install this agent skill to your local

pnpm dlx add-skill https://github.com/Dexploarer/claudius-skills/tree/HEAD/examples/intermediate/performance-skills/lighthouse-ci-integrator

Skill Files

Browse the full folder contents for lighthouse-ci-integrator.

Download Skill

Loading file tree…

examples/intermediate/performance-skills/lighthouse-ci-integrator/SKILL.md

Skill Metadata

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".

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