Perf Lighthouse

作者 tech-leads-club120b67676388无许可证收录于 2026年10月8日更新于 2026年10月8日

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 生成的概览

指导通过 CLI、Node API、性能预算和 CI 集成运行 Lighthouse 性能审计。

功能
该技能提供通过 CLI 或 Node API 在本地运行 Lighthouse 审计的说明,包括设备形态、节流和类别选择等常用参数。它展示如何在 budget.json 中定义性能预算,以及如何解析 Lighthouse JSON 报告以获取评分、Core Web Vitals 和未通过的审计项。它还涵盖 Lighthouse CI 配置、GitHub Actions 设置、构建对比和故障排查。
适用场景
适用于衡量站点性能、解读 Lighthouse 评分、设置性能预算或将审计集成到 CI 中。它不用于修复具体的性能问题或 Astro 专属优化。
运行要求
需要 Node.js 和 npm 来安装 Lighthouse 或 @lhci/cli,需要 Chrome/Chromium 浏览器(可能需要设置 CHROME_PATH),并需要网络访问以审计 URL。CI 示例涉及 GitHub Actions 和可选的 LHCI_GITHUB_APP_TOKEN 密钥。该技能不附带脚本,仅为说明文档。

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

来源与署名

来源:tech-leads-club/agent-skills位于packages/skills-catalog/skills/(performance)/perf-lighthouse提交120b676

许可证: 无许可证

内容归原作者所有。SourceWeft 从公开仓库中收录这些内容。

举报或申请下架