Perf Lighthouse

by tech-leads-club120b67676388No licenseListed Oct 8, 2026Updated Oct 8, 2026

Run Lighthouse audits locally via CLI or Node API, parse and interpret reports, and set performance budgets. Use when measuring site performance, understanding Lighthouse scores, setting up budgets, or integrating audits into CI. Triggers on: lighthouse, run lighthouse, lighthouse score, performance audit, performance budget. Do NOT use for fixing specific performance issues (use perf-web-optimization or core-web-vitals) or Astro-specific optimization (use perf-astro).

AI-generated overview

Guides running Lighthouse performance audits via CLI, Node API, budgets, and CI integration.

What it does
This skill provides instructions for running Lighthouse audits locally through the CLI or Node API, including common flags for form factor, throttling, and category selection. It shows how to define performance budgets in a budget.json file and how to parse Lighthouse JSON reports for scores, Core Web Vitals, and failed audits. It also covers Lighthouse CI configuration, GitHub Actions setup, build comparison, and troubleshooting.
When to use it
Use it when measuring site performance, interpreting Lighthouse scores, setting performance budgets, or integrating audits into CI. It is not intended for fixing specific performance issues or Astro-specific optimization.
Requirements
Requires Node.js and npm to install Lighthouse or @lhci/cli, a Chrome/Chromium browser (CHROME_PATH may be needed), and network access to audit URLs. CI examples reference GitHub Actions and an optional LHCI_GITHUB_APP_TOKEN secret. No scripts ship with the skill; it is instructions only.

Lighthouse Audits

CLI Quick Start

bash
# Installnpm install -g lighthouse
# Basic auditlighthouse https://example.com
# Mobile performance only (faster)lighthouse https://example.com --preset=perf --form-factor=mobile
# Output JSON for parsinglighthouse https://example.com --output=json --output-path=./report.json
# Output HTML reportlighthouse https://example.com --output=html --output-path=./report.html

Common Flags

bash
--preset=perf           # Performance only (skip accessibility, SEO, etc.)--form-factor=mobile    # Mobile device emulation (default)--form-factor=desktop   # Desktop--throttling-method=devtools  # More accurate throttling--only-categories=performance,accessibility  # Specific categories--chrome-flags="--headless"   # Headless Chrome

Performance Budgets

Create budget.json:

json
[  {    "resourceSizes": [      { "resourceType": "script", "budget": 200 },      { "resourceType": "image", "budget": 300 },      { "resourceType": "stylesheet", "budget": 50 },      { "resourceType": "total", "budget": 500 }    ],    "resourceCounts": [{ "resourceType": "third-party", "budget": 5 }],    "timings": [      { "metric": "interactive", "budget": 3000 },      { "metric": "first-contentful-paint", "budget": 1500 },      { "metric": "largest-contentful-paint", "budget": 2500 }    ]  }]

Run with budget:

bash
lighthouse https://example.com --budget-path=./budget.json

Node API

javascript
import lighthouse from 'lighthouse'import * as chromeLauncher from 'chrome-launcher'
async function runAudit(url) {  const chrome = await chromeLauncher.launch({ chromeFlags: ['--headless'] })
  const result = await lighthouse(url, {    port: chrome.port,    onlyCategories: ['performance'],    formFactor: 'mobile',    throttling: {      cpuSlowdownMultiplier: 4,    },  })
  await chrome.kill()
  const { performance } = result.lhr.categories  const { 'largest-contentful-paint': lcp } = result.lhr.audits
  return {    score: Math.round(performance.score * 100),    lcp: lcp.numericValue,  }}

GitHub Actions

yaml
# .github/workflows/lighthouse.ymlname: Lighthouse
on:  pull_request:  push:    branches: [main]
jobs:  lighthouse:    runs-on: ubuntu-latest    steps:      - uses: actions/checkout@v4
      - name: Build site        run: npm ci && npm run build
      - name: Run Lighthouse        uses: treosh/lighthouse-ci-action@v11        with:          urls: |            http://localhost:3000            http://localhost:3000/about          budgetPath: ./budget.json          uploadArtifacts: true          temporaryPublicStorage: true        env:          LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}

Lighthouse CI (LHCI)

For full CI integration with historical tracking:

bash
# Installnpm install -g @lhci/cli
# Initialize configlhci wizard

Creates lighthouserc.js:

javascript
module.exports = {  ci: {    collect: {      url: ['http://localhost:3000/', 'http://localhost:3000/about'],      startServerCommand: 'npm run start',      numberOfRuns: 3,    },    assert: {      assertions: {        'categories:performance': ['error', { minScore: 0.9 }],        'categories:accessibility': ['warn', { minScore: 0.9 }],        'first-contentful-paint': ['error', { maxNumericValue: 1500 }],        'largest-contentful-paint': ['error', { maxNumericValue: 2500 }],        'cumulative-layout-shift': ['error', { maxNumericValue: 0.1 }],      },    },    upload: {      target: 'temporary-public-storage', // or 'lhci' for self-hosted    },  },}

Run:

bash
lhci autorun

Parse JSON Report

javascript
import fs from 'fs'
const report = JSON.parse(fs.readFileSync('./report.json'))
// Overall scores (0-1, multiply by 100 for percentage)const scores = {  performance: report.categories.performance.score,  accessibility: report.categories.accessibility.score,  seo: report.categories.seo.score,}
// Core Web Vitalsconst vitals = {  lcp: report.audits['largest-contentful-paint'].numericValue,  cls: report.audits['cumulative-layout-shift'].numericValue,  fcp: report.audits['first-contentful-paint'].numericValue,  tbt: report.audits['total-blocking-time'].numericValue,}
// Failed auditsconst failed = Object.values(report.audits)  .filter((a) => a.score !== null && a.score < 0.9)  .map((a) => ({ id: a.id, score: a.score, title: a.title }))

Compare Builds

bash
# Save baselinelighthouse https://prod.example.com --output=json --output-path=baseline.json
# Run on PRlighthouse https://preview.example.com --output=json --output-path=pr.json
# Compare (custom script)node compare-reports.js baseline.json pr.json

Simple comparison script:

javascript
const baseline = JSON.parse(fs.readFileSync(process.argv[2]))const pr = JSON.parse(fs.readFileSync(process.argv[3]))
const metrics = ['largest-contentful-paint', 'cumulative-layout-shift', 'total-blocking-time']
metrics.forEach((metric) => {  const base = baseline.audits[metric].numericValue  const current = pr.audits[metric].numericValue  const diff = (((current - base) / base) * 100).toFixed(1)  const emoji = current <= base ? '✅' : '❌'  console.log(`${emoji} ${metric}: ${diff}% (${base.toFixed(0)} → ${current.toFixed(0)})`)})

Troubleshooting

IssueSolution
Inconsistent scoresRun multiple times (--number-of-runs=3), use median
Chrome not foundSet CHROME_PATH env var
TimeoutsIncrease with --max-wait-for-load=60000
Auth requiredUse --extra-headers or puppeteer script

Source and attribution

Source:tech-leads-club/agent-skillsinpackages/skills-catalog/skills/(performance)/perf-lighthouseat commit120b676

License: No license

Content belongs to its original authors. SourceWeft indexes it from a public repository.

Report or request removal