---
name: fuckingfast
description: Speed-audit a site or app against Google Lighthouse and produce a stack-safe performance fix plan. Fingerprints the tech stack first (static HTML, Vite SPA, Next.js SSG/ISR/SSR, etc.) so no proposed fix breaks the rendering model, runs Lighthouse (mobile + desktop) against the production URL or a local production build, presents ranked findings with impact vs risk, then asks before changing anything. On a yes it writes fuckingfast.md at the project root as the working plan, references it in the project droid.md/CLAUDE.md, and works through the fixes re-testing after each one. Use when the user wants to check or improve site/app speed, Core Web Vitals, or Lighthouse scores. Invoke as /fuckingfast [url or project path].
---

# fuckingfast — Lighthouse audit + stack-safe speed plan

**Golden rule: the current rendering/tech model is the baseline, not the problem.** Never propose a fix that migrates the stack (SPA → SSR, Pages → App Router, static → framework, etc.) or silently changes how routes render. Fixes must work *within* what the project already is.

## Step 1 — Fingerprint the stack (this decides which fixes are safe)

Read the project droid.md/CLAUDE.md and PROJECT_PLAN.md first. Then verify against the code — if docs and code disagree, trust the code and say so:

- `package.json` scripts + deps → framework (Next.js / Vite / plain), React or not, Tailwind or not
- `next.config.*` → `output` mode, image config, redirects/headers
- Bare `index.html` + no bundler → static HTML site
- `netlify.toml` / `.netlify/` → Netlify-hosted; note any plugins (e.g. `@netlify/plugin-nextjs`)
- Legacy Vite/Lovable projects: audit and fix as-is, never migrate (house rule)

Classify every audited page as one of: **STATIC** (plain HTML) · **SPA** (client-rendered Vite/CRA) · **NEXT-PRERENDERED** (SSG/ISR — `○`/`●` in build output) · **NEXT-DYNAMIC** (SSR — `ƒ`). For Next.js, run `npm run build` and record the route markers — **this map is the invariant every fix must preserve.** Re-check it after every change (the `cookies()`/`headers()` gotcha in ~/Sites/CLAUDE.md silently flips ISR/SSG routes to per-request dynamic with no build warning).

## Step 2 — Pick the test target (never audit a dev server)

Dev servers give garbage scores (no minification, HMR overhead). In priority order:

1. **URL passed as argument** — use it.
2. **Live production URL** from droid.md or `netlify status`/`netlify open:site`. Prefer this — it includes real CDN, headers, and compression. (Read-only fetches; fine without confirmation.)
3. **Local production build**: kill stray dev servers (`pkill -f "npm run dev"`), then Next → `npm run build && npm run start` on the project's port from the ~/Sites/CLAUDE.md port table; Vite → `npm run build` then `npx serve dist -l <port>`; static → `npx serve . -l <port>`. Note in the report that local results lack CDN/compression, so treat them as relative, not absolute.

Audit the homepage plus 1–2 representative pages (e.g. a blog post, a main app screen) — not just `/`.

## Step 3 — Run Lighthouse

Global CLI (v12+) is installed. Per page, run mobile (default) and desktop:

```
lighthouse <url> --output=json --output=html \
  --output-path=./docs/lighthouse/<page>-<mobile|desktop> \
  --chrome-flags="--headless=new" --quiet
```

Save reports to `<project>/docs/lighthouse/` — `/docs` is gitignored by house convention, so reports never hit the repo. Pull scores (Performance / Accessibility / Best Practices / SEO) and the top opportunities + diagnostics from the JSON, with estimated ms savings.

## Step 4 — Map findings to stack-SAFE fixes only

Filter every Lighthouse opportunity through the Step 1 fingerprint. Typical mapping:

| Finding | STATIC | SPA | NEXT |
|---|---|---|---|
| Unoptimised images | `<picture>`/WebP, width/height attrs | same + lazy import | `next/image` (check `images` config first) |
| Render-blocking CSS/JS | defer/async, inline critical CSS | code-split routes, dynamic `import()` | `next/dynamic`, check bundle with build output |
| No text compression / caching | Netlify headers file | same | usually Netlify plugin handles it — verify, don't duplicate |
| Web fonts | `font-display: swap`, preload | same | `next/font` |
| Unused JS | remove dead scripts | tree-shake, audit deps | audit client components — but NEVER convert server/client components just for score |
| Slow TTFB on ISR/SSG page | n/a | n/a | check for accidental dynamic rendering (route marker flipped) — that's the fix, not caching hacks |

Rules: no new dependencies without `~/Sites/safe-npm-install.sh`; nothing that alters the route map, `next.config` output mode, or hosting; accessibility/SEO fixes are in scope only if trivial and zero-risk — flag the rest as follow-ups.

## Step 5 — Show the plan, then ASK

Present: current scores per page/device → ranked fix list (each with: what, estimated impact, effort, risk, and *why it's safe for this stack*) → what will deliberately NOT be touched. Then ask explicitly: **"Want me to get started?"** Do not touch a single file before the yes.

- **No / not now** → offer to save the plan as `fuckingfast.md` anyway for later; otherwise leave only the reports in `/docs/lighthouse/`.

## Step 6 — On yes: write fuckingfast.md and reference it

1. Write `<project>/fuckingfast.md`: date (verify via `python3 ~/Sites/tools/whatday.py`), test target + method, stack fingerprint + route-map invariant, baseline scores, the plan as a checklist (`- [ ]`), and a re-test log section.
2. Reference it in the project **droid.md** (which CLAUDE.md symlinks to — edit the real file): add a short `## Performance` note pointing at `fuckingfast.md`. If the project has neither, create droid.md per house convention first.
3. British English in the doc, unless the project's droid.md declares otherwise.

## Step 7 — Implement one fix at a time, prove it

For each item, in ranked order: apply → `npm run build` must pass (and for Next.js the route markers must be unchanged) → re-run Lighthouse on the affected page → record before/after in fuckingfast.md's re-test log → tick the checkbox. If a fix regresses the score or breaks the build and the repair isn't mechanical, **revert it**, mark it "attempted — parked" with the reason, and move on.

Never push or deploy — that's /wrapup's job and needs its own explicit yes. Local re-tests after fixes won't match live scores; say so, and suggest a live re-audit after the next deploy. End with the standard report: Files changed / What was modified / Files intentionally not touched / Follow-up needed.
