web-perf-cilisted
Install: claude install-skill YosefHayim/dufflebag
# Web Performance CI (Core Web Vitals)
Put a **measured performance budget** between a change and production. Three gates, each watching a different truth:
| Layer | Tool | Answers | Runs |
| --- | --- | --- | --- |
| **Lab** | Lighthouse CI (`lhci autorun`) | "Did this PR regress in a controlled test?" | every PR |
| **Field** | Chrome UX Report (CrUX) API | "What do real users actually experience?" | after deploy / weekly |
| **RUM** | `web-vitals` (optional) | "Which element/script caused it, per page?" | in the live app |
The budget numbers are the same everywhere (one SSOT): **LCP ≤ 2.5s · INP ≤ 200ms · CLS ≤ 0.1**, plus FCP ≤ 1.8s, TTFB ≤ 0.8s, Lighthouse performance ≥ 0.90. **Field data comes from the Chrome UX Report (CrUX) API** — Google is retiring CrUX data from PageSpeed Insights, so `runCrux.mjs` reads CrUX directly while PSI stays the lab source. New here? read `TECH-GLOSSARY.md` first; the model is in `CONTEXT.md`.
## Ground rule
**INP is a field-only metric** — it needs a real user interacting, so Lighthouse's lab run can't produce it. In the lab gate we assert **Total Blocking Time (TBT)** as INP's proxy; the true INP comes from the field (PSI/CrUX) and your RUM. Never claim an INP number from a lab run.
## Front door — grill first, then wire (via grill-me)
Interview the user one question at a time; **recommend an answer for each**, and if the repo already answers it, explore the repo instead of asking. Walk the tree in order — each answer changes what