perf-lighthouse — Claude Code skill: what it does, how to install
Runs local Lighthouse audits via CLI or Node API, parses reports, and configures performance budgets. Useful for tracking Core Web Vitals and integrating speed checks into CI.
npx skills add tech-leads-club/agent-skills --skill perf-lighthouse -a claude-codeWhat perf-lighthouse does
This skill sets up and runs Lighthouse audits through the terminal and Node API without opening browser DevTools. It generates JSON or HTML reports, launches headless Chrome, and enforces size thresholds using a budget.json configuration. Presets cover mobile emulation and network throttling.
For continuous integration, the skill provides Lighthouse CI settings and workflow steps for GitHub Actions. Code snippets show how to read metrics like LCP and CLS from raw JSON, then compare values between two builds before merging.
This skill focuses strictly on measuring scores and asserting budgets. It will not fix layout bugs or rewrite Astro templates; those tasks require separate optimization skills. Running audits locally requires Google Chrome and the global lighthouse package.
What it helps with
- run local Lighthouse audits via CLI or Node API
- enforce asset size and timing budgets in budget.json
- configure Lighthouse CI for pull request checks in GitHub Actions
- parse JSON reports to compare Web Vitals between builds
Example prompts for the agent
- run a mobile Lighthouse audit for my local dev server and output report.json
- create a budget.json file to limit JavaScript bundle size and LCP timing
- show the Lighthouse CI configuration for automated GitHub Actions checks
How to install perf-lighthouse
1Skills CLI (Vercel)
npx skills add tech-leads-club/agent-skills --skill perf-lighthouse -a claude-code2Manually: put the files in place
~/.claude/skills/perf-lighthouse/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/perf-lighthouse/
1Skills CLI (Vercel)
npx skills add tech-leads-club/agent-skills --skill perf-lighthouse -a codex2Manually: put the files in place
.agents/skills/perf-lighthouse/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add tech-leads-club/agent-skills --skill perf-lighthouse -a cursor2Manually: put the files in place
.cursor/skills/perf-lighthouse/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install tech-leads-club/agent-skills perf-lighthouse2Manually: put the files in place
.github/skills/perf-lighthouse/SKILL.md1Skills CLI (Vercel)
npx skills add tech-leads-club/agent-skills --skill perf-lighthouse -a gemini-cli2Platform CLI
gemini skills install https://github.com/tech-leads-club/agent-skills --path 'packages/skills-catalog/skills/(performance)/perf-lighthouse'Manually: put the files in place
.devin/skills/perf-lighthouse/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add tech-leads-club/agent-skills --skill perf-lighthouse -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about perf-lighthouse
How do I install perf-lighthouse in Claude Code?
Run npx skills add tech-leads-club/agent-skills --skill perf-lighthouse -a claude-code in your terminal.
What does perf-lighthouse do?
It automates Lighthouse performance audits through the CLI and Node API, parses audit JSON, and configures budget limits for CI workflows.
Does perf-lighthouse fix performance issues directly?
No, it measures performance and enforces budgets. The author notes that code remediation should be handled by skills like perf-web-optimization or perf-astro.
Source text
SKILL.md · MIT
---
name: perf-lighthouse
description: '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).'
---
# Lighthouse Audits
## CLI Quick Start
```bash
# Install
npm install -g lighthouse
# Basic audit
lighthouse https://example.com
# Mobile performance only (faster)
lighthouse https://example.com --preset=perf --form-factor=mobile
# Output JSON for parsing
lighthouse https://example.com --output=json --output-path=./report.json
# Output HTML report
lighthouse 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.yml
name: 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
# Install
npm install -g @lhci/cli
# Initialize config
lhci 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 Vitals
const 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 audits
const 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 baseline
lighthouse https://prod.example.com --output=json --output-path=baseline.json
# Run on PR
lighthouse 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
| Issue | Solution |
| ------------------- | ----------------------------------------------------- |
| Inconsistent scores | Run multiple times (`--number-of-runs=3`), use median |
| Chrome not found | Set `CHROME_PATH` env var |
| Timeouts | Increase with `--max-wait-for-load=60000` |
| Auth required | Use `--extra-headers` or puppeteer script |
© tech-leads-club · MIT · tech-leads-club/agent-skills