Skip to content

Commit f3f15fd

Browse files
authored
Merge pull request #67 from nucliweb/perf/reduce-skill-context-duplication
perf: reduce context duplication in WebPerf skills (-16.6% lines)
2 parents 538196a + dc9c31d commit f3f15fd

100 files changed

Lines changed: 7679 additions & 1493 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/skills/SCHEMA.md

Lines changed: 0 additions & 643 deletions
This file was deleted.

.claude/skills/webperf-core-web-vitals/SKILL.md

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ JavaScript snippets for measuring web performance in Chrome DevTools. Execute wi
2525
- `scripts/LCP-Video-Candidate.js` — LCP Video Candidate
2626
- `scripts/LCP.js` — Largest Contentful Paint (LCP)
2727

28-
Descriptions and thresholds: `references/snippets.md`
2928

3029
## Common Workflows
3130

@@ -54,7 +53,7 @@ When LCP is slow or the user asks "debug LCP" or "why is LCP slow":
5453
When layout shifts are detected or the user asks "debug CLS" or "layout shift issues":
5554

5655
1. **CLS.js** - Measure overall CLS score
57-
2. **Layout-Shift-Loading-and-Interaction.js** (from Interaction skill) - Separate loading vs interaction shifts
56+
2. **Layout-Shift-Loading-and-Interaction.js** _(pending — available in webperf-interaction skill)_
5857
3. Cross-reference with **webperf-loading** skill:
5958
- Find-Above-The-Fold-Lazy-Loaded-Images.js (lazy images causing shifts)
6059
- Fonts-Preloaded-Loaded-and-used-above-the-fold.js (font swap causing shifts)
@@ -63,11 +62,11 @@ When layout shifts are detected or the user asks "debug CLS" or "layout shift is
6362

6463
When interactions feel slow or the user asks "debug INP" or "slow interactions":
6564

66-
1. **INP.js** - Measure overall INP value
67-
2. **Interactions.js** (from Interaction skill) - List all interactions with timing
68-
3. **Input-Latency-Breakdown.js** (from Interaction skill) - Break down input delay, processing, presentation
69-
4. **Long-Animation-Frames.js** (from Interaction skill) - Identify blocking animation frames
70-
5. **Long-Animation-Frames-Script-Attribution.js** (from Interaction skill) - Find scripts causing delays
65+
1. **INP.js** - Measure overall INP value; call `getINP()` after interactions, `getINPDetails()` for full list
66+
2. **Interactions.js** _(pending — available in webperf-interaction skill)_
67+
3. **Input-Latency-Breakdown.js** _(pending — available in webperf-interaction skill)_
68+
4. **Long-Animation-Frames.js** _(pending — available in webperf-interaction skill)_
69+
5. **Long-Animation-Frames-Script-Attribution.js** _(pending — available in webperf-interaction skill)_
7170

7271
### Video as LCP Investigation
7372

@@ -146,7 +145,7 @@ Use this decision tree to automatically run follow-up snippets based on results:
146145

147146
### After CLS.js
148147

149-
- **If CLS > 0.1** → Run **webperf-interaction:Layout-Shift-Loading-and-Interaction.js** to separate causes
148+
- **If CLS > 0.1** → Run **webperf-interaction:Layout-Shift-Loading-and-Interaction.js** _(pending — available in webperf-interaction skill)_
150149
- **If CLS > 0.25 (poor)** → Run comprehensive shift investigation:
151150
1. **webperf-loading:Find-Above-The-Fold-Lazy-Loaded-Images.js** (images without dimensions)
152151
2. **webperf-loading:Fonts-Preloaded-Loaded-and-used-above-the-fold.js** (font loading strategy)
@@ -163,9 +162,20 @@ Use this decision tree to automatically run follow-up snippets based on results:
163162
3. **webperf-interaction:Long-Animation-Frames.js** (blocking frames)
164163
4. **webperf-interaction:Long-Animation-Frames-Script-Attribution.js** (culprit scripts)
165164
- **If specific interaction type is slow (e.g., keyboard)** → Focus analysis on that interaction type
165+
- **After INP data is collected** → call `getINPDetails()` for the full sorted interaction list (useful for identifying patterns across multiple slow interactions)
166+
167+
### Error Recovery
168+
169+
- **If any script returns `status: "error"`** → Check if the page has finished loading:
170+
- If early in load: wait and re-run the script
171+
- If page is an SPA: user may need to navigate to the target route first
172+
- **If LCP.js / LCP-Sub-Parts.js returns `status: "error"`** → Tell the user: "LCP data is not available yet. Please ensure the page has fully loaded, then run the analysis again."
173+
- **If INP.js `getINP()` returns `status: "error"`** → The `getDataFn: "getINP"` field signals the agent can retry after user interaction. Prompt the user to click, type, or scroll, then call `getINP()` again.
166174

167175
### Cross-Skill Triggers
168176

177+
> **Context fork note:** This skill runs with `context: fork`. Cross-skill triggers below are **recommendations to report back to the parent agent**, not direct calls this subagent can execute. When a cross-skill trigger fires, tell the user which skill and script to run next. Scripts marked _(pending)_ are not yet available — skip them and note the limitation.
178+
169179
These triggers recommend using snippets from other skills:
170180

171181
#### From LCP to Loading Skill
@@ -223,6 +233,4 @@ When multiple CWV metrics are poor, prioritize investigation:
223233
## References
224234

225235
- `references/snippets.md` — Descriptions and thresholds for each script
226-
- `references/schema.md` — Return value schema for interpreting script output
227-
228-
> Execute via `mcp__chrome-devtools__evaluate_script` → read with `mcp__chrome-devtools__get_console_message`.
236+
- `references/schema.md` — Return value schema for interpreting script output

.claude/skills/webperf-core-web-vitals/references/schema.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ Keep the existing `async () => {}` wrapper. Add a `return` statement with struct
186186
```
187187
188188
#### CLS
189+
Returns buffered CLS immediately and keeps tracking. Always call `getCLS()` after interactions to get an updated value.
189190
```json
190191
{
191192
"script": "CLS",
@@ -194,9 +195,12 @@ Keep the existing `async () => {}` wrapper. Add a `return` statement with struct
194195
"value": 0.05,
195196
"unit": "score",
196197
"rating": "good",
197-
"thresholds": { "good": 0.1, "needsImprovement": 0.25 }
198+
"thresholds": { "good": 0.1, "needsImprovement": 0.25 },
199+
"message": "CLS tracking active. Call getCLS() for updated value after page interactions.",
200+
"getDataFn": "getCLS"
198201
}
199202
```
203+
`getCLS()` returns the same shape with the latest accumulated value.
200204
201205
#### INP (tracking)
202206
```json
@@ -224,6 +228,15 @@ Keep the existing `async () => {}` wrapper. Add a `return` statement with struct
224228
}
225229
}
226230
```
231+
If no interactions yet, `getINP()` returns `status: "error"` with `getDataFn: "getINP"` — retry after user interaction.
232+
233+
`getINPDetails()` returns the full sorted interaction list (array of up to 15 entries). Use when `getINP()` shows poor INP and you need to identify patterns across multiple slow interactions:
234+
```json
235+
[
236+
{ "formattedName": "click → button.submit", "duration": 450, "startTime": 1200,
237+
"phases": { "inputDelay": 120, "processingTime": 280, "presentationDelay": 50 } }
238+
]
239+
```
227240
228241
#### LCP-Sub-Parts
229242
```json

.claude/skills/webperf-core-web-vitals/scripts/CLS.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.claude/skills/webperf-core-web-vitals/scripts/INP.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.claude/skills/webperf-core-web-vitals/scripts/LCP-Image-Entropy.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)