benchmark
Skill8 starsChanged 6 months agoMITView on GitHub
Web performance benchmark: median page timings, Web Vitals and bundle sizes vs a baseline.
95 other projects use a version of this, 5 of them edited.
Adopted by
Most recently taken up by
- Rojios/everything-claude-codetheir own version, first seen Nov 8, 2026
- accso/ai-context-mcptheir own version, first seen Nov 8, 2026
- pankaj-mahaur/Agent-Daemontheir own version, first seen Nov 6, 2026
- datafusion-contrib/datafusion-distributedtheir own version, first seen Nov 2, 2026
- menot-you/n-soultheir own version, first seen Nov 1, 2026
- sebyx07/ruby2htmltheir own version, first seen Nov 1, 2026
Used with
Projects with it also use ios-clean, ios-fix and 4 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
Saqlain-811Skillios-clean
Remove the DebugBridge SPM package and all #if DEBUG wiring from an iOS app. (gstack)
Also in 5 projects that use this
Saqlain-811Skillios-fix
Autonomous iOS bug fixer. (gstack)
Also in 5 projects that use this
seek888Skillopen-gstack-browser
Launch GStack Browser — AI-controlled Chromium with the sidebar extension baked in. Opens a visible browser window where you can watch every action in real time. The sidebar shows a live activity feed and chat. Anti-bot stealth built in. Use when asked to "open gstack browser", "launch browser", "connect chrome", "open chrome", "real browser", "launch chrome", "side panel", or "control my browser". Voice triggers (speech-to-text aliases): "show me the browser".
Also in 8 projects that use this
ShreyRaviSkillsetup-gbrain
Set up gbrain for this coding agent: install the CLI, initialize a local PGLite or Supabase brain, register MCP, capture per-remote trust policy. One command from zero to "gbrain is running, and this agent can call it." Use when: "setup gbrain", "connect gbrain", "start gbrain", "install gbrain", "configure gbrain for this machine". (gstack)
Also in 6 projects that use this
ShreyRaviSkillsync-gbrain
Keep gbrain current with this repo's code and refresh agent search guidance in CLAUDE.md. Wraps the gstack-gbrain-sync orchestrator with state probing, native code-surface registration, capability checks, and a verdict block. Re-runnable, idempotent. Use when: "sync gbrain", "refresh gbrain", "re-index this repo", "gbrain search isn't finding things". (gstack)
Also in 6 projects that use this
- +1 more from Saqlain-811
Other versions95 projects use a version of this.
Word for word · 0
None found.
Edited · 5
- mr-daedalium/ostack-saas★ 10823% same
- no-session/pstack★ 9628% same
- lucas-flatwhite/gstack-ko★ 4527% same
- CarbeneAI/Forge★ 921% same
- Samin12/skills★ 820% same
Wrote their own version · 90
- garrytan/gstack★ 141ksame name
- dragonflydb/dragonfly★ 32ksame name
- xtermjs/xterm.js★ 21ksame name
- udecode/plate★ 17ksame name
- Z3Prover/z3★ 13ksame name
- androidx/androidx★ 6.1ksame name
- samchon/typia★ 6ksame name
- PaddlePaddle/FastDeploy★ 3.7ksame name
- zalando/skipper★ 3.3ksame name
- samchon/nestia★ 2.2ksame name
80 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository62 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- address-pr-reviewSkill
- agent-evalSkill
- ai-cost-guardSkill
- autoplanSkill
- aws-costSkill
- bedrock-guardrailsSkill
- browseSkill
- canarySkill
- carefulSkill
- claudeSkill
- codexSkill
- connect-chromeSkill
- connect-reviewSkill
- context-restoreSkill
- context-saveSkill
- csoSkill
- design-consultationSkill
- design-htmlSkill
- design-reviewSkill
- design-shotgunSkill
- devex-reviewSkill
- diagramSkill
- document-generateSkill
- document-releaseSkill
- freezeSkill
- guardSkill
- healthSkill
- iac-reviewSkill
- improve-archSkill
- investigateSkill
- kb-reviewSkill
- land-and-deploySkill
- landing-reportSkill
- learnSkill
- make-pdfSkill
- mcp-reviewSkill
- office-hoursSkill
- open-browserSkill
- pair-agentSkill
- plan-ceo-reviewSkill
- plan-design-reviewSkill
- plan-devex-reviewSkill
- plan-eng-reviewSkill
- plan-tuneSkill
- pr-summarySkill
- qa-onlySkill
- qaSkill
- retroSkill
- reviewSkill
- scrapeSkill
- setup-browser-cookiesSkill
- setup-deploySkill
- shipSkill
- skillifySkill
- specSkill
- telegramSkill
- unfreezeSkill
- unslopSkill
- vibe-gcSkill
- The first 60 shown.
The file
Show its rules and text
We split this skill into the rules it gives an agent
15 rules. 0 are common, 8 are distinctive, and 7 are very specific to this project.
0
Common
Most of the 81 edited versions we read keep these.
8
Distinctive
This author's own choices. Worth a look.
7
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 17
If this session was compacted, the copy of this skill in context may be cut off.
- Very specific: line 18
Read ${CLAUDE_SKILL_DIR}/SKILL.md from disk and resume at the step you are on.
- Distinctive: line 22
Use when: "performance", "benchmark", "page speed", "lighthouse", "web vitals", "bundle size", "load time".
- Distinctive: line 26
Not for comparing models or prompts (use /agent-eval or /deliberation:ask-all), nor for API latency or build timing (use the …
- Very specific: line 61
When the user types /benchmark, run this skill.
- Very specific: line 85
Use --pages when given; otherwise run $B links and keep only same-origin links, dropping any URL whose path matches …
- Very specific: line 94
Every metric for one run comes from one page load: a fresh goto, then a single js call that waits for the load event, watches LCP for 3 s, …
- Distinctive: line 159
If baseline exists, compare current medians against it:
- Distinctive: line 196
When a metric matches both, REGRESSION takes precedence over WARNING.
- Very specific: line 200
When either side has only one run (a legacy baseline, or --quick), timing rows are INCONCLUSIVE: one load cannot separate a change from …
- Very specific: line 201
No baseline: report the absolute medians and the budget check, give the verdict as inconclusive, and suggest --baseline.
- Distinctive: line 244
Before writing the report, decide what the numbers actually say, and put that first.
- Distinctive: line 249
no difference: every timing median sits inside its baseline range and no size row is a REGRESSION.
- Distinctive: line 250
inconclusive: no baseline, a one-run side, timings that moved both ways, or a page whose loads failed.
- Distinctive: line 280
Measure, don't guess: Use actual performance.getEntries() data, not estimates.
“Common” is measured: kept by at least 6 in 10 of the 81 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
If this session was compacted, the copy of this skill in context may be cut off.
Read ${CLAUDE_SKILL_DIR}/SKILL.md from disk and resume at the step you are on.
When to invoke
Use when: "performance", "benchmark", "page speed", "lighthouse", "web vitals", "bundle size", "load time".
Voice triggers (speech-to-text aliases): "speed test", "check performance".
Not for comparing models or prompts (use /agent-eval or /deliberation:ask-all), nor for API latency or build timing (use the performance-benchmarker agent).
Preamble
eval "$("${VIBESTACK_HOME:-$HOME/.vibestack}/bin/vibe-slug" 2>/dev/null)" 2>/dev/null || SLUG="unknown"
_LEARN_FILE="${VIBESTACK_HOME:-$HOME/.vibestack}/projects/${SLUG:-unknown}/learnings.jsonl"
if [ -f "$_LEARN_FILE" ]; then
_LEARN_COUNT=$(wc -l < "$_LEARN_FILE" 2>/dev/null | tr -d ' ')
echo "LEARNINGS: $_LEARN_COUNT entries loaded"
if [ "$_LEARN_COUNT" -gt 5 ] 2>/dev/null; then
"${VIBESTACK_HOME:-$HOME/.vibestack}/bin/vibe-learnings-search" --limit 5 2>/dev/null || true
fi
else
echo "LEARNINGS: none yet"
fi{{include lib/snippets/session-host.md}}
{{include lib/snippets/decision-brief.md}}
{{include lib/snippets/working-protocols.md}}
{{include lib/snippets/state-protocols.md}}
You are a Performance Engineer who has optimized apps serving millions of requests. You know that performance doesn't degrade in one big regression — it dies by a thousand paper cuts. Each PR adds 50ms here, 20KB there, and one day the app takes 8 seconds to load and nobody knows when it got slow.
SETUP
{{include lib/snippets/browse-detect.md}}
User-invocable
When the user types /benchmark, run this skill.
Arguments
/benchmark <url>— full performance audit with baseline comparison/benchmark <url> --baseline— capture baseline (run before making changes)/benchmark <url> --quick— one run, no verdict: absolute timings and the budget check only/benchmark <url> --pages /,/dashboard,/api/health— specify pages/benchmark --diff— benchmark only pages affected by current branch/benchmark --trend— show performance trends from historical data
Instructions
Phase 1: Setup
eval "$("${VIBESTACK_HOME:-$HOME/.vibestack}/bin/vibe-slug" 2>/dev/null || echo "SLUG=unknown")"
mkdir -p .vibestack/benchmark-reports
mkdir -p .vibestack/benchmark-reports/baselines
# Refresh stat info so --diff sees only real content changes.
git update-index --refresh >/dev/null 2>&1 || truePhase 2: Page Discovery
Use --pages when given; otherwise run $B links and keep only same-origin links, dropping any URL whose path matches logout|signout|delete|remove|cancel|unsubscribe (case-insensitive) before presenting or visiting them.
If --diff mode:
git diff $(gh pr view --json baseRefName -q .baseRefName 2>/dev/null || gh repo view --json defaultBranchRef -q .defaultBranchRef.name 2>/dev/null || echo main)...HEAD --name-onlyPhase 3: Performance Data Collection
Every metric for one run comes from one page load: a fresh goto, then a single js call that waits for the load event, watches LCP for 3 s, and returns everything at once.
B='<BROWSE_BIN>'
$B goto <page-url>
$B js "(async()=>{document.readyState==='complete'||await new Promise(r=>addEventListener('load',r,{once:true}));await new Promise(r=>setTimeout(r,0));const nav=performance.getEntriesByType('navigation')[0]?.toJSON()??null;const fcp=performance.getEntriesByType('paint').find(e=>e.name==='first-contentful-paint')?.startTime??null;const lcp=await new Promise(r=>{let v=null;new PerformanceObserver(l=>{const e=l.getEntries();if(e.length)v=e[e.length-1].startTime}).observe({type:'largest-contentful-paint',buffered:true});setTimeout(()=>r(v),3000)});const all=performance.getEntriesByType('resource');const brief=e=>({name:e.name.split('/').pop().split('?')[0],type:e.initiatorType,size:e.transferSize,duration:Math.round(e.duration)});const resources=all.map(brief).sort((a,b)=>b.duration-a.duration).slice(0,15);const scripts=all.filter(e=>e.initiatorType==='script').map(brief);const css=all.filter(e=>e.initiatorType==='css'||e.name.split('?')[0].endsWith('.css')).map(brief);const summary={total_requests:all.length,total_transfer:all.reduce((t,e)=>t+(e.transferSize||0),0),by_type:Object.entries(all.reduce((a,e)=>{a[e.initiatorType]=(a[e.initiatorType]||0)+1;return a},{})).sort((a,b)=>b[1]-a[1])};return JSON.stringify({nav,fcp,lcp,resources,scripts,css,summary})})()"A failed load is not a measurement. When the status is not 2xx — nav.responseStatus, or the code goto printed when that field is 0 or missing — or the goto itself errors, the run fails: record it as a failed load, keep no metrics from it, and count it in the report. A page with no successful run has no numbers.
Repeat runs. Do 5 runs per page (each a fresh goto plus the one js call). For every metric keep the per-metric median and its [min,max] across the successful runs. --quick does a single run. Every table shows medians; the range is what the comparison judges against.
Metrics, from the returned JSON (the navigation entry's startTime is 0, so its fields are already relative to navigation start):
- TTFB:
nav.responseStart - nav.requestStart - FCP:
fcp - LCP:
lcp(the last entry seen within 3 s) - DOM Interactive / DOM Complete / Full Load:
nav.domInteractive/nav.domComplete/nav.loadEventEnd - Requests / transfer:
summary; JS / CSS bundle: the sum ofsizeoverscripts/css; slowest resources:resources
A missing FCP or LCP (null) is recorded as null and shown as missing in every table — never 0, and never a PASS in the budget table.
Phase 4: Baseline Capture (--baseline mode)
Save metrics to baseline file:
{
"url": "<url>",
"timestamp": "<ISO>",
"branch": "<branch>",
"runs": 5,
"pages": {
"/": {
"failed_loads": 0,
"ttfb_ms": 120,
"fcp_ms": 450,
"lcp_ms": 800,
"dom_interactive_ms": 600,
"dom_complete_ms": 1200,
"full_load_ms": 1400,
"total_requests": 42,
"total_transfer_bytes": 1250000,
"js_bundle_bytes": 450000,
"css_bundle_bytes": 85000,
"range_ms": {
"ttfb_ms": [110, 140],
"fcp_ms": [420, 490],
"lcp_ms": [760, 870],
"dom_interactive_ms": [570, 640],
"dom_complete_ms": [1150, 1260],
"full_load_ms": [1350, 1480]
},
"largest_resources": [
{"name": "main.js", "size": 320000, "duration": 180},
{"name": "vendor.js", "size": 130000, "duration": 90}
]
}
}
}Metric values are the medians; range_ms holds each timing's [min,max]; runs is the number of runs per page. Write to .vibestack/benchmark-reports/baselines/baseline.json. Only --baseline mode writes this file; it is the comparison baseline. A baseline without runs (written before repeat runs existed) counts as 1 run with no range.
Phase 5: Comparison
If baseline exists, compare current medians against it:
PERFORMANCE REPORT — [url]
══════════════════════════
VERDICT: slower — LCP and Full Load regressed outside the baseline range (5 runs each, 0 failed or non-2xx loads)
Branch: [current-branch] vs baseline ([baseline-branch])
Page: /
─────────────────────────────────────────────────────
Metric Baseline Range Current Delta Status
──────── ──────── ───── ─────── ───── ──────
TTFB 120ms 110-140ms 135ms +15ms OK
FCP 450ms 420-490ms 480ms +30ms OK
LCP 800ms 760-870ms 1600ms +800ms REGRESSION
DOM Interactive 600ms 570-640ms 650ms +50ms OK
DOM Complete 1200ms 1150-1260ms 1350ms +150ms OK
Full Load 1400ms 1350-1480ms 2100ms +700ms REGRESSION
Total Requests 42 58 +16 WARNING
Transfer Size 1.2MB 1.8MB +0.6MB REGRESSION
JS Bundle 450KB 720KB +270KB REGRESSION
CSS Bundle 85KB 88KB +3KB OK
REGRESSIONS DETECTED: 4
[1] LCP doubled (800ms → 1600ms) — likely a large new image or blocking resource
[2] Full Load +700ms (1400ms → 2100ms) — over the 500ms absolute threshold
[3] Total transfer +50% (1.2MB → 1.8MB) — check new JS bundles
[4] JS bundle +60% (450KB → 720KB) — new dependency or missing tree-shakingRegression thresholds:
- Timing metrics: >50% increase OR >500ms absolute increase = REGRESSION
- Timing metrics: >20% increase = WARNING
- Bundle size: >25% increase = REGRESSION
- Bundle size: >10% increase = WARNING
- Request count: >30% increase = WARNING
- Bundle-size thresholds also apply to total transfer size.
- When a metric matches both, REGRESSION takes precedence over WARNING.
Noise and edge rules (applied before the thresholds above):
- A timing whose current median sits inside the baseline range (
range_ms) is OK whatever its delta — that difference is run-to-run noise. - When either side has only one run (a legacy baseline, or
--quick), timing rows are INCONCLUSIVE: one load cannot separate a change from noise. Byte and request counts are deterministic and are still judged. - No baseline: report the absolute medians and the budget check, give the verdict as inconclusive, and suggest
--baseline. - A baseline value of 0 or
nullhas no percentage: show the absolute delta, apply only the absolute 500ms rule to timings, and mark size rows N/A rather than dividing by zero.
Phase 6: Slowest Resources
TOP 10 SLOWEST RESOURCES
═════════════════════════
# Resource Type Size Duration
1 vendor.chunk.js script 320KB 480ms
2 main.js script 250KB 320ms
3 hero-image.webp img 180KB 280ms
4 analytics.js script 45KB 250ms ← third-party
5 fonts/inter-var.woff2 font 95KB 180ms
...
RECOMMENDATIONS:
- vendor.chunk.js: Consider code-splitting — 320KB is large for initial load
- analytics.js: Load async/defer — blocks rendering for 250ms
- hero-image.webp: Add width/height to prevent CLS, consider lazy loadingPhase 7: Performance Budget
Check the medians against industry budgets. Per row: under 90% of budget = PASS; 90-100% of budget = WARNING (below the budget itself); at or over budget = FAIL; a missing metric = N/A. The grade is the share of metrics under budget (PASS + WARNING), N/A rows left out of the count: A = all, B ≥ 80%, C ≥ 60%, D ≥ 40%, F below.
PERFORMANCE BUDGET CHECK
════════════════════════
Metric Budget Actual Status
──────── ────── ────── ──────
FCP < 1.8s 0.48s PASS
LCP < 2.5s 1.6s PASS
Total JS < 500KB 720KB FAIL
Total CSS < 100KB 88KB PASS
Total Transfer < 2MB 1.8MB WARNING (90%)
HTTP Requests < 50 58 FAIL
Grade: C (4/6 under budget)Vet the number
Before writing the report, decide what the numbers actually say, and put that first. The report opens with one line:
VERDICT: <faster | slower | no difference | inconclusive> — <one-clause reason> (<runs> runs each, <n> failed or non-2xx loads)
- faster / slower: the timings that left the baseline range all moved one way (any size REGRESSION also means slower).
- no difference: every timing median sits inside its baseline range and no size row is a REGRESSION.
- inconclusive: no baseline, a one-run side, timings that moved both ways, or a page whose loads failed. Say which.
Then name the limiter: the slowest first-party resource from Phase 6, or the metric furthest over budget — the one thing most worth fixing. A verdict built on failed or non-2xx loads is not a verdict; report the count instead of averaging around it.
Phase 8: Trend Analysis (--trend mode)
Load the timestamped .vibestack/benchmark-reports/baselines/*-benchmark.json files, sorted by name (oldest first), and show trends:
PERFORMANCE TRENDS (last 5 benchmarks)
══════════════════════════════════════
Date FCP LCP Bundle Requests Grade
2026-03-10 420ms 750ms 380KB 38 A
2026-03-12 440ms 780ms 410KB 40 A
2026-03-14 450ms 800ms 450KB 42 A
2026-03-16 460ms 850ms 520KB 48 B
2026-03-18 480ms 1600ms 720KB 58 B
TREND: Performance degrading. LCP doubled in 8 days.
JS bundle growing 50KB/week. Investigate.Phase 9: Save Report
Take one UTC timestamp for the run (date -u +%Y%m%dT%H%M%SZ) and write .vibestack/benchmark-reports/<UTC timestamp>-benchmark.md and .vibestack/benchmark-reports/<UTC timestamp>-benchmark.json.
On every run that collected metrics, in any mode, also write the metrics JSON (the Phase 4 shape) to an immutable .vibestack/benchmark-reports/baselines/<UTC timestamp>-benchmark.json with the same timestamp. Never overwrite an existing timestamped file; --trend reads these.
Important Rules
- Measure, don't guess. Use actual performance.getEntries() data, not estimates.
- Baseline is essential. Without a baseline, you can report absolute numbers but can't detect regressions. Always encourage baseline capture.
- Relative thresholds, not absolute. 2000ms load time is fine for a complex dashboard, terrible for a landing page. Compare against YOUR baseline.
- Third-party scripts are context. Flag them, but the user can't fix Google Analytics being slow. Focus recommendations on first-party resources.
- Bundle size is the leading indicator. Load time varies with network. Bundle size is deterministic. Track it religiously.
- Read-only. Produce the report. Don't modify code unless explicitly asked.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

