Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

Back to skills

Lighthouse

BSecurity

Lighthouse audit of one page with an improvement loop until targets are met. Triggers "lighthouse", "page speed", "LCP", "CLS", "INP", "core web vitals". Repo-wide performance audits go to /audit performance.

44 stars
0 votes
0 copies
2 views
Added 9/3/2026
ai-agentsjavascripttypescriptgojavaswiftshellbashnextjsnodetesting

Works with

climcp

Security Analysis

B84/100
mediumInstalls packages at runtime which could introduce malicious dependencies
mediumInstalls packages at runtime which could introduce malicious dependencies

Scanned 9/20/2026

Install to Claude Code

$npx -y skills add darkroomengineering/cc-settings --skill lighthouse --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Lighthouse?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Lighthouse
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/darkroomengineering-lighthouse/badge)](https://www.skillsdirectory.com/skills/darkroomengineering-lighthouse)

More formats (shields.io, HTML) on the badges page.

Download Zip
Files
SKILL.md
---
name: lighthouse
description: Lighthouse audit of one page with an improvement loop until targets are met. Triggers "lighthouse", "page speed", "LCP", "CLS", "INP", "core web vitals". Repo-wide performance audits go to /audit performance.
context: fork
argument-hint: "[url]"
allowed-tools:
  - Bash
  - Read
  - Write
  - Edit
  - Grep
  - Glob
  - LS
  - mcp__chrome-devtools__navigate_page
  - mcp__chrome-devtools__take_screenshot
  - mcp__chrome-devtools__take_snapshot
  - mcp__chrome-devtools__lighthouse_audit
  - mcp__aside-devtools__navigate_page
  - mcp__aside-devtools__take_screenshot
  - mcp__aside-devtools__take_snapshot
  - mcp__aside-devtools__lighthouse_audit
requires:
  - command: lighthouse
    install: "npm i -g lighthouse (CLI, used for batched 3x3 averaged audits)"
  - mcp: [chrome-devtools, aside-devtools]
    optional: true
    install: "Either DevTools MCP adds on-demand audits and visual regression screenshots; the CLI loop runs without one."
---

# Lighthouse Optimization Loop

Set a product-neutral scratch root once:

```bash
LIGHTHOUSE_DIR="${TMPDIR:-/tmp}/cc-settings-lighthouse"
mkdir -p "$LIGHTHOUSE_DIR"
```

Use the Chrome DevTools MCP only when the user configured it. Standalone Codex
otherwise uses the Lighthouse CLI plus native/manual screenshots; if no visual
capture path exists, stop before changing UI and report that visual regression
verification is unavailable. This package does not auto-run unpinned registry
MCP packages.

**Method:** 3 mobile + 3 desktop runs per audit, averaged for reliability. After each code change, re-audit and visually verify the page with the configured MCP or the stated manual fallback.

---

## Setup

1. **Parse URL** from `$ARGUMENTS`. If no URL, ask the user. Default: `http://localhost:3000`

2. **Verify prerequisites:**
   ```bash
   lighthouse --version    # CLI must be installed for the batched 3x3 protocol
   ```
   If lighthouse is missing: `npm install -g lighthouse`
   If runs fail with a chrome-launcher error or every metric comes back
   `NO_LCP`/null, no system Chrome exists — find a real Chrome/Chromium binary
   (Chrome for Testing, Playwright's `chromium-*` — NOT `chrome-headless-shell`,
   which produces NO_LCP) and export `CHROME_PATH=<binary>` before the loop.
   Record which binary was used; a before/after comparison is only clean when
   both sides ran the same binary.
   Check whether a DevTools MCP is registered, as `chrome-devtools` or as
   `aside-devtools` (same package, different name): use whichever prefix is in
   your tool list. Neither is required; without one, skip the screenshot steps
   and rely on the CLI numbers. Do not install or auto-run an unpinned registry
   MCP on their behalf.

3. **Create results directory:**
   ```bash
   mkdir -p "$LIGHTHOUSE_DIR"
   ```

4. **Take baseline screenshots** before any changes:
   - `mcp__chrome-devtools__navigate_page` (type: "url", url: `<url>`)
   - `mcp__chrome-devtools__take_screenshot`

   Describe the current layout, key elements, and visual state. This is your **visual baseline** — you will compare against it after every change to catch regressions.

5. **Confirm with user:** Show the URL, confirm the dev server is running, ask if there are specific pages or routes to audit beyond the main URL.

---

## Audit Protocol

Each audit consists of **3 mobile + 3 desktop runs**, averaged per category.

### Run the audits

```bash
# Mobile runs (Lighthouse default is mobile)
for i in 1 2 3; do
  lighthouse <url> \
    --output=json \
    --output-path="$LIGHTHOUSE_DIR/mobile-$i.json" \
    --chrome-flags="--headless --no-sandbox" \
    --only-categories=performance,accessibility,best-practices,seo \
    --quiet \
    2>/dev/null
done

# Desktop runs
for i in 1 2 3; do
  lighthouse <url> \
    --output=json \
    --output-path="$LIGHTHOUSE_DIR/desktop-$i.json" \
    --chrome-flags="--headless --no-sandbox" \
    --preset=desktop \
    --only-categories=performance,accessibility,best-practices,seo \
    --quiet \
    2>/dev/null
done
```

### Extract scores

For each JSON result file:
```bash
cat "$LIGHTHOUSE_DIR/mobile-1.json" | \
  jq '{
    performance: (.categories.performance.score * 100),
    accessibility: (.categories.accessibility.score * 100),
    bestPractices: (.categories["best-practices"].score * 100),
    seo: (.categories.seo.score * 100)
  }'
```

### Compute averages

Average the 3 runs per category for both mobile and desktop. Report as:

```
## Audit Results

| Category | Mobile (avg) | Desktop (avg) |
|----------|-------------|---------------|
| Performance | XX | XX |
| Accessibility | XX | XX |
| Best Practices | XX | XX |
| SEO | XX | XX |
```

### Extract failing audits

From the JSON, find specific audits that failed or scored poorly:
```bash
cat "$LIGHTHOUSE_DIR/mobile-1.json" | \
  jq '.audits | to_entries[] | select(.value.score != null and .value.score < 0.9) | {id: .key, score: .value.score, title: .value.title, description: .value.displayValue}'
```

Sort by impact (lowest scores first). These drive the improvement loop.

---

## Diagnose From the JSON, Not From a Narrative

Before planning any fix, re-derive the bottleneck from the report you just ran.
Prior session notes, state files, and issue write-ups go stale and get root
causes wrong — treat them as hypotheses to check against the JSON, never as the
diagnosis. Fetch the team-knowledge index and read any note whose title
matches the failing audit names; the fetch command is in
docs/knowledge-system.md (fail-open — skip if `gh` is unavailable).

**Classify the perf gap first:**

- **TBT high (hundreds of ms)** → main-thread problem. Long tasks, hydration,
  script execution. `mainthread-work-breakdown` and `long-tasks` tell you where.
- **TBT low (~tens of ms) but LCP high under `throttlingMethod=simulate`** →
  bytes-on-critical-path problem, NOT execution. Lantern replays observed
  traffic over simulated slow 4G, so eager bytes inflate LCP even when the page
  is actually fast. Fixes that defer *execution* will not move this; only
  removing or lazy-loading *bytes* will.

Do not read `mainthread-work-breakdown`'s total as "blocking work before
paint" — it is the whole page load. TBT is the blocking measure.

**For bytes-on-critical-path gaps, attribute before fixing:**

```bash
jq '.audits["resource-summary"].details.items[] | {resourceType, requestCount, transferSize}' "$LIGHTHOUSE_DIR/mobile-1.json"
jq '.audits["bootup-time"].details.items[:5]' "$LIGHTHOUSE_DIR/mobile-1.json"
jq '.audits["network-requests"].details.items | sort_by(-.transferSize)[:10] | .[] | {transferSize, resourceType, url}' "$LIGHTHOUSE_DIR/mobile-1.json"
```

For a full attribution of a route's JS by package and app directory, and the
measured fix ladder for bytes-on-critical-path gaps (AVIF, per-route CSS
chunking, font subsetting with `unicode-range`, platform elements over client
widgets), use `~/.claude/skills/audit/references/performance-playbook.md` and
its two harness scripts. If a hosted runner (PageSpeed Insights) reports "the
page stopped responding" while local runs pass, the page runs WebGL on a
software renderer: reproduce with
`--chrome-flags='--headless=new --disable-gpu --use-gl=angle --use-angle=swiftshader'`
and gate the canvas on the renderer string (playbook rung 7).

Hunt for bytes that ship but do nothing: preloaded fonts no style consumes
(a grep hit on the font file may be its own declaration — check for a real
consumer), and libraries a `next/dynamic` wrapper claims to defer while a
second static import path pulls them in anyway. Verify eager-path claims
against the build manifest (`.next/build-manifest.json` on Next.js), not
against the wrapper's existence. A `next/dynamic({ssr:false})` component that
renders unconditionally still fetches its chunk at hydration — deferral only
pays when the render is conditional.

---

## Improvement Loop

> **Autonomous mode:** to drive this loop turn-by-turn without re-prompting, set
> `/goal mobile and desktop scores in all four categories meet their targets, or stop after 20 rounds`.
> A goal evaluator (Haiku by default) reads the audit table after each turn and decides whether to continue.
> See [/goal docs](https://code.claude.com/docs/en/goal).

```
LOOP until all scores >= 90 or user interrupts:

  1. IDENTIFY the lowest-scoring category and its top failing audits
     - Read the Lighthouse audit details for specific recommendations
     - Cross-reference with the project's performance rules

  2. PLAN one targeted fix
     - Focus on the highest-impact failing audit
     - One fix at a time — never batch multiple unrelated changes
     - Common fixes by audit:
       • render-blocking-resources → async/defer scripts, inline critical CSS
       • largest-contentful-paint → priority attribute, preload, optimize image
       • cumulative-layout-shift → explicit dimensions, font-display
       • unused-javascript → dynamic imports, code splitting
       • uses-responsive-images → srcSet + sizes, `next/image` (satus) or `<picture>`/`vite-imagetools` (novus), proper dimensions
       • uses-text-compression → verify gzip/brotli enabled
       • image-size-responsive → width/height attributes
       • unminified-javascript → check build config
       • dom-size → reduce DOM nodes, virtualize lists
       • third-party-summary → defer/lazy-load third-party scripts
       • font-display → font-display: swap or optional
       • offscreen-images → loading="lazy" (NOT on above-fold/LCP images)

  3. IMPLEMENT the fix
     - Edit the relevant source files
     - Keep changes minimal and focused

  4. VERIFY BUILD
     - Run the project build to ensure no compilation errors
     - If TypeScript project: `tsc --noEmit` first

  5. VISUAL REGRESSION CHECK
     - `mcp__chrome-devtools__navigate_page` to the same URL
     - `mcp__chrome-devtools__take_screenshot`
     - Compare against the baseline screenshot:
       • Layout intact? (same general structure, no collapsed/missing sections)
       • Content visible? (text, images, interactive elements still present)
       • Styling correct? (colors, spacing, typography not broken)
       • Functionality preserved? (interactive elements still look clickable)
     - If regression detected: REVERT the change immediately and try a different approach
     - Also check critical user flows if the change affects interactive elements:
       - `mcp__chrome-devtools__take_snapshot` (a11y tree — confirms interactive elements are present, returns `uid`s)
       - `mcp__chrome-devtools__take_screenshot` (visual verification)

  6. RE-AUDIT
     - Run full audit protocol again (3 mobile + 3 desktop)
     - Compare against previous scores

  7. LOG RESULTS
     - Append to `$LIGHTHOUSE_DIR/results.tsv`:
       round	mobile_perf	desktop_perf	mobile_a11y	desktop_a11y	status	description
     - Status: "kept" (scores improved), "reverted" (regression or no improvement)

  8. REPORT
     - Show score delta: "Performance: 72 → 85 (+13)"
     - Show what was changed and why
     - Show the current failing audits for the next round
     - Every claimed delta needs BOTH sides measured on the SAME basis:
       • Bundle/byte savings: never quote a number from one build. Wipe the
         build output dir on both sides first — chunk dirs accumulate stale
         hashed files across builds, and a dirty-dir comparison can invert
         the sign of the result.
       • Never compare transfer bytes (from the Lighthouse JSON) against
         on-disk bytes — same basis or no claim.
       • A change measured worse gets reported worse, then reverted.

  9. CONTINUE to next round
```

---

## Visual Regression Protocol

This is the critical safety net. Performance changes MUST NOT break the UI.

### After every code change:

1. **Navigate:** `mcp__chrome-devtools__navigate_page` (type: "url", url: `<url>`)
2. **Screenshot:** `mcp__chrome-devtools__take_screenshot`
3. **Compare** against baseline:
   - Is the page layout the same structure?
   - Are all visible elements still present?
   - Is text readable and properly styled?
   - Are images displaying correctly?
   - Are interactive elements (buttons, forms, nav) visually intact?

### Regression = immediate revert

If any visual regression is detected:
1. `git checkout -- <changed-files>` to revert
2. Log status as "reverted (visual regression)" in results.tsv
3. Try an alternative approach to the same audit issue
4. NEVER accept a performance improvement that breaks the UI

### Multi-page checks

If the user specified multiple URLs/routes, check ALL of them after each change. A fix that improves the homepage but breaks a subpage is still a regression.

---

## Targets

Default targets (override by telling the agent different ones):

| Category | Mobile | Desktop |
|----------|--------|---------|
| Performance | >= 90 | >= 95 |
| Accessibility | >= 95 | >= 95 |
| Best Practices | >= 95 | >= 95 |
| SEO | >= 95 | >= 95 |

The loop continues until ALL categories on BOTH mobile and desktop meet their targets, or the user interrupts.

---

## Core Web Vitals Focus

When Performance score is low, prioritize these metrics:

| Metric | Target | What to Fix |
|--------|--------|-------------|
| LCP < 2.5s | Optimize largest content element (usually hero image or heading). Use `priority`, `fetchpriority="high"`, preload, optimize image format/size. |
| INP < 200ms | Reduce JavaScript execution time. Debounce handlers, use `startTransition`, yield to main thread with `scheduler.yield()`. |
| CLS < 0.1 | Set explicit dimensions on images/video/ads/embeds. Use `font-display: optional`. Reserve space for dynamic content. |
| TTFB < 800ms | Server-side: check caching, CDN, database queries. Use streaming SSR with `Suspense`. |

---

## Dashboard

After each round, write `$LIGHTHOUSE_DIR/dashboard.md`:

```markdown
# Lighthouse Optimization: <url>
Updated: <timestamp>

## Current Scores
| Category | Mobile | Desktop | Target | Status |
|----------|--------|---------|--------|--------|
| Performance | XX | XX | 90/95 | pass/fail |
| Accessibility | XX | XX | 95/95 | pass/fail |
| Best Practices | XX | XX | 95/95 | pass/fail |
| SEO | XX | XX | 95/95 | pass/fail |

## Progress (baseline → current)
| Category | Mobile | Desktop |
|----------|--------|---------|
| Performance | 62 → 91 (+29) | 78 → 96 (+18) |
| ... |

## Changes Applied
| Round | Fix | Mobile Perf Delta | Visual QA |
|-------|-----|-------------------|-----------|
| 1 | Added priority to hero image | +12 | pass |
| 2 | Deferred analytics script | +8 | pass |
| 3 | Added font-display: swap | +3 | pass |

## Remaining Issues
Top failing audits still to address...
```

---

## Completion

When all targets are met:
1. Print final score summary with deltas from baseline
2. List all changes made (files modified and why)
3. Suggest running a final full visual QA: `/qa <url>`
4. Do NOT auto-commit — let the user review the changes first

Attribution

darkroomengineeringdarkroomengineering
View sourceMore from darkroomengineering →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Caveman

Ultra-compressed communication mode that cuts output tokens while keeping technical accuracy. Levels: lite, full, ultra and the wenyan variants. Use for /caveman, "caveman mode", "talk like caveman", "be brief" or "less tokens".

1066601 votes

Hyperplan

Adversarial multi-agent planning skill. Self-orchestrates 5 hostile category members (unspecified-low, unspecified-high, deep, ultrabrain, artistry) via team-mode for ruthless cross-critique debate, distills only the defensible insights, then MANDATORILY hands the distilled insight bundle to the `plan` agent for executable plan formalization. Use when planning needs maximum rigor and surfacing of weak assumptions, blind spots, and over-engineering. Triggers: 'hyperplan', 'hpp', '/hyperplan', ...

686011 votes

Mcp Code Execution

Routes multi-tool workflows through MCP servers for large datasets and pipelines. Use when Bash tool overhead is limiting throughput on data-heavy tasks.

3351 votes

catchup

Recovers the conversation and failed tool calls of a previous Codex, Claude Code, Antigravity, Cline, Copilot CLI, Cursor, DeepSeek Harness, Kimi, OpenCode, Pi Agent, or ZCode session. Use when the user says "catch up", "what did the last session do", "get me up to speed", "I switched agents", asks to recover/summarize a previous session before continuing, or asks to diagnose or report a catchup failure. Do NOT use for the current conversation, git history, or any non-agent log.

651 votes

math-skill

A comprehensive mathematical reasoning skill for AI assistants — handles arithmetic to research-level problems with rigorous step-by-step reasoning, systematic verification, and transparent uncertainty handling

381 votes
View all in ai-agents →