AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Web Perf Ci

skill-yosefhayim-dufflebag-web-perf-ci · by YosefHayim

Wires automated website-performance gates into CI/CD and enforces Core Web Vitals budgets (LCP, INP, CLS). Sets up a Lighthouse CI budget check on every PR (lab), a Chrome UX Report (CrUX) real-user field check after deploy, and an optional web-vitals RUM snippet. Grills the repo to detect the stack and how the site runs (static build, dev server, or preview URL), then writes lighthouserc, the Gi…

No reviews yet
0 installs
15 views
0.0% view→install

Install

$ agentstack add skill-yosefhayim-dufflebag-web-perf-ci

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-yosefhayim-dufflebag-web-perf-ci)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
1mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Web Perf Ci? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

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 you write:

  1. Which surfaces do we gate? → recommend the homepage + the two highest-traffic templates (a listing + a detail page), not every route.
  2. How does the site run for a test? (staticDistDir a built folder · startServerCommand a dev server · a deployed preview URL) → auto-detect from package.json + host: Astro/Vite/Next static export → staticDistDir; an app server → startServerCommand; Cloudflare Pages/Vercel PR previews → preview URL.
  3. Enforce or observe first? → recommend shipping assertions as warn for ~1–2 weeks to learn the baseline, then flip the Core Web Vitals to error.
  4. Do we have field data? (a PSI API key + enough traffic for CrUX) → recommend adding PSI_API_KEY as a repo secret; if traffic is thin, CrUX will be NONE — lean on lab + your own RUM until it fills.
  5. Wire RUM now? (web-vitals in the app → which sink: your /rum endpoint, GA4, etc.) → recommend yes only if a sink exists; otherwise defer and note it.
  6. Where do results land? (temporary-public-storage PR link vs a self-hosted LHCI server) → recommend temporary-public-storage to start.

Setup workflow

Run once the interview settles. Reuse the shipped templates/ and scripts/ — copy and adapt, don't hand-roll:

  1. Detect the stack + run mode (step 2 above). Confirm the build command and the served URL/dir.
  2. Write lighthouserc.json at repo root from templates/lighthouserc.json; set the collect block to the detected run mode and keep the Core Web Vitals assertions. Full option map: reference/lighthouse-ci.md.
  3. Write the lab workflow .github/workflows/lighthouse-ci.yml from templates/lighthouse-ci.yml (checkout → setup-node → npm ci → build if present → npx @lhci/cli autorun).
  4. Wire the field check (Lab + Field): copy scripts/runCrux.mjs (the durable field source) to .github/perf/ and add .github/workflows/field-check.yml from the template (runs on successful deployment_status + weekly cron). Add a PSI_API_KEY secret — a Google key with both the PageSpeed Insights API and the Chrome UX Report API enabled. It reads templates/budgets.json and exits non-zero when a real-user Core Web Vital is poor; "no CrUX record" (low traffic) passes. Also copy runPagespeed.mjs if you want an on-demand lab check via PSI.
  5. (Optional) RUM — copy templates/web-vitals.js into the app entry, point ENDPOINT at the sink, npm i web-vitals. It uses the attribution build so a bad score names its cause. Details: reference/web-vitals-rum.md.
  6. Verify — locally: npx @lhci/cli autorun against a build, and node scripts/runPagespeed.mjs https://your-url --strategy=mobile with a key. Show the before/after and the exact files written; get approval before committing.

Canonical lab budget (lighthouserc.json)

{
  "ci": {
    "collect": { "staticDistDir": "./dist", "numberOfRuns": 3 },
    "assert": {
      "preset": "lighthouse:recommended",
      "assertions": {
        "categories:performance": ["error", { "minScore": 0.9 }],
        "largest-contentful-paint": ["error", { "maxNumericValue": 2500 }],
        "cumulative-layout-shift": ["error", { "maxNumericValue": 0.1 }],
        "total-blocking-time": ["error", { "maxNumericValue": 200 }],
        "first-contentful-paint": ["warn", { "maxNumericValue": 1800 }],
        "server-response-time": ["warn", { "maxNumericValue": 800 }]
      }
    },
    "upload": { "target": "temporary-public-storage" }
  }
}

Swap collect for the run mode: { "startServerCommand": "npm run start", "url": ["http://localhost:3000/"] } or { "url": ["https://preview.example.com/"] }. total-blocking-time is the lab stand-in for INP.

Field check (Chrome UX Report API)

Real-user field data comes from the CrUX API — the durable source, since PSI is dropping its CrUX (loadingExperience) data. PSI stays useful for the lab score.

# real-user Core Web Vitals (p75) — exits 1 on a "poor" vital, passes if no CrUX record
node scripts/runCrux.mjs https://example.com --form-factor=PHONE --key=$PSI_API_KEY
# lab score (+ legacy PSI field data while it lasts)
node scripts/runPagespeed.mjs https://example.com --strategy=mobile --key=$PSI_API_KEY

runCrux.mjs reads each vital's 75th percentile, falls back from the exact URL to the origin, and treats "no CrUX record" (low traffic) as a pass. Endpoints + response shapes: reference/crux-api.md (field), reference/pagespeed-insights.md (lab).

Honest scope — what we do NOT wire

  • mod_pagespeed / ngx_pagespeed (PageSpeed Module) — Google archived it (~2021). Do optimization at build time (bundler, image pipeline) and at the CDN edge instead. Name it, don't install it.
  • Google Hosted Libraries CDN — browser cache partitioning (~2020) erased the shared-cache win; self-host/bundle is faster now (one less third-party DNS+TLS hop).
  • Google Public DNS (8.8.8.8) — a client-side resolver choice, not a CI gate; the real TTFB lever is a fast CDN/DNS for your own domain.

Files

  • CONTEXT.md — the lab/field/RUM model and where each metric is observable
  • TECH-GLOSSARY.md — every acronym (LCP, INP, CLS, CrUX, RUM, TTFB, …)
  • README.md — harness setup (API key), script + template catalog, a full example
  • reference/lighthouse-ci.md — lighthouserc, presets, budgets, autorun, GitHub Action
  • reference/pagespeed-insights.md — PSI v5 endpoint (lab source; PSI field data is deprecating)
  • reference/crux-api.md — CrUX API endpoint, request/response — the durable field source
  • reference/web-vitals-rum.md — the RUM snippet, attribution, sending to analytics
  • scripts/runCrux.mjs — zero-dep CrUX API field checker (p75 real-user vitals) → exits 1 on a poor vital
  • scripts/runPagespeed.mjs — zero-dep PSI v5 checker → lab score (+ legacy field), exits 1 on breach
  • templates/lighthouserc.json, lighthouse-ci.yml, field-check.yml, budgets.json, web-vitals.js

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.