Skip to content

Commit 23f87e2

Browse files
committed
chore: sync schema docs, skill references, MDX pages and snippets
- Update webperf skill schema references across .claude/skills and skills/ - Update Loading MDX pages (Back-Forward-Cache, Cache-Strategy-Analysis, Client-Side-Redirect-Detection, First-And-Third-Party-Script-Info, Resource-Hints-Validation, Validate-Preload-Async-Defer-Scripts) - Update First-And-Third-Party-Script-Info snippet - Update cli/README.md and reporters unit tests - Update README.md and public/llms-full.txt
1 parent d81bb7b commit 23f87e2

21 files changed

Lines changed: 1273 additions & 469 deletions

File tree

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

Lines changed: 92 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,15 @@ Scripts that read DOM or `performance.getEntriesByType()` directly. Return JSON
8585
console.log(`TTFB: ${value}ms (${rating})`);
8686

8787
// Agent output
88-
return { script: "TTFB", status: "ok", metric: "TTFB", value, unit: "ms", rating,
89-
thresholds: { good: 800, needsImprovement: 1800 } };
88+
return {
89+
script: "TTFB",
90+
status: "ok",
91+
metric: "TTFB",
92+
value,
93+
unit: "ms",
94+
rating,
95+
thresholds: { good: 800, needsImprovement: 1800 },
96+
};
9097
})();
9198
```
9299

@@ -137,11 +144,12 @@ return {
137144
script: "INP",
138145
status: "tracking",
139146
message: "INP tracking active. Interact with the page then call getINP() for results.",
140-
getDataFn: "getINP"
147+
getDataFn: "getINP",
141148
};
142149
```
143150
144151
**Agent workflow for tracking scripts:**
152+
145153
```
146154
1. evaluate_script(INP.js) → { status: "tracking", getDataFn: "getINP" }
147155
2. (user interacts with the page)
@@ -167,6 +175,7 @@ Keep the existing `async () => {}` wrapper. Add a `return` statement with struct
167175
### Core Web Vitals
168176
169177
#### LCP
178+
170179
```json
171180
{
172181
"script": "LCP",
@@ -179,14 +188,16 @@ Keep the existing `async () => {}` wrapper. Add a `return` statement with struct
179188
"details": {
180189
"element": "img.hero",
181190
"elementType": "Image",
182-
"url": "https://example.com/hero.jpg",
191+
"url": "https://web.dev/hero.jpg",
183192
"sizePixels": 756000
184193
}
185194
}
186195
```
187196
188197
#### CLS
198+
189199
Returns buffered CLS immediately and keeps tracking. Always call `getCLS()` after interactions to get an updated value.
200+
190201
```json
191202
{
192203
"script": "CLS",
@@ -200,9 +211,11 @@ Returns buffered CLS immediately and keeps tracking. Always call `getCLS()` afte
200211
"getDataFn": "getCLS"
201212
}
202213
```
214+
203215
`getCLS()` returns the same shape with the latest accumulated value.
204216
205217
#### INP (tracking)
218+
206219
```json
207220
{
208221
"script": "INP",
@@ -211,7 +224,9 @@ Returns buffered CLS immediately and keeps tracking. Always call `getCLS()` afte
211224
"getDataFn": "getINP"
212225
}
213226
```
227+
214228
`getINP()` returns:
229+
215230
```json
216231
{
217232
"script": "INP",
@@ -228,17 +243,24 @@ Returns buffered CLS immediately and keeps tracking. Always call `getCLS()` afte
228243
}
229244
}
230245
```
246+
231247
If no interactions yet, `getINP()` returns `status: "error"` with `getDataFn: "getINP"` — retry after user interaction.
232248
233249
`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:
250+
234251
```json
235252
[
236-
{ "formattedName": "click → button.submit", "duration": 450, "startTime": 1200,
237-
"phases": { "inputDelay": 120, "processingTime": 280, "presentationDelay": 50 } }
253+
{
254+
"formattedName": "click → button.submit",
255+
"duration": 450,
256+
"startTime": 1200,
257+
"phases": { "inputDelay": 120, "processingTime": 280, "presentationDelay": 50 }
258+
}
238259
]
239260
```
240261
241262
#### LCP-Subparts
263+
242264
```json
243265
{
244266
"script": "LCP-Subparts",
@@ -263,6 +285,7 @@ If no interactions yet, `getINP()` returns `status: "error"` with `getDataFn: "g
263285
```
264286
265287
#### LCP-Trail
288+
266289
```json
267290
{
268291
"script": "LCP-Trail",
@@ -277,13 +300,20 @@ If no interactions yet, `getINP()` returns `status: "error"` with `getDataFn: "g
277300
"finalElement": "img.hero",
278301
"candidates": [
279302
{ "index": 1, "selector": "h1", "time": 800, "elementType": "Text block" },
280-
{ "index": 2, "selector": "img.hero", "time": 1240, "elementType": "Image", "url": "hero.jpg" }
303+
{
304+
"index": 2,
305+
"selector": "img.hero",
306+
"time": 1240,
307+
"elementType": "Image",
308+
"url": "hero.jpg"
309+
}
281310
]
282311
}
283312
}
284313
```
285314
286315
#### LCP-Image-Entropy
316+
287317
```json
288318
{
289319
"script": "LCP-Image-Entropy",
@@ -300,13 +330,23 @@ If no interactions yet, `getINP()` returns `status: "error"` with `getDataFn: "g
300330
}
301331
},
302332
"items": [
303-
{ "url": "hero.jpg", "width": 1200, "height": 630, "fileSizeBytes": 156000, "bpp": 1.65, "isLowEntropy": false, "lcpEligible": true, "isLCP": true }
333+
{
334+
"url": "hero.jpg",
335+
"width": 1200,
336+
"height": 630,
337+
"fileSizeBytes": 156000,
338+
"bpp": 1.65,
339+
"isLowEntropy": false,
340+
"lcpEligible": true,
341+
"isLCP": true
342+
}
304343
],
305344
"issues": []
306345
}
307346
```
308347
309348
#### LCP-Video-Candidate
349+
310350
```json
311351
{
312352
"script": "LCP-Video-Candidate",
@@ -318,7 +358,7 @@ If no interactions yet, `getINP()` returns `status: "error"` with `getDataFn: "g
318358
"thresholds": { "good": 2500, "needsImprovement": 4000 },
319359
"details": {
320360
"isVideo": true,
321-
"posterUrl": "https://example.com/hero.avif",
361+
"posterUrl": "https://web.dev/hero.avif",
322362
"posterFormat": "avif",
323363
"posterPreloaded": true,
324364
"fetchpriorityOnPreload": "high",
@@ -332,6 +372,7 @@ If no interactions yet, `getINP()` returns `status: "error"` with `getDataFn: "g
332372
### Loading
333373
334374
#### TTFB
375+
335376
```json
336377
{
337378
"script": "TTFB",
@@ -345,6 +386,7 @@ If no interactions yet, `getINP()` returns `status: "error"` with `getDataFn: "g
345386
```
346387
347388
#### TTFB-Sub-Parts
389+
348390
```json
349391
{
350392
"script": "TTFB-Sub-Parts",
@@ -369,6 +411,7 @@ If no interactions yet, `getINP()` returns `status: "error"` with `getDataFn: "g
369411
```
370412
371413
#### Find-render-blocking-resources
414+
372415
```json
373416
{
374417
"script": "Find-render-blocking-resources",
@@ -380,12 +423,20 @@ If no interactions yet, `getINP()` returns `status: "error"` with `getDataFn: "g
380423
"byType": { "link": 2, "script": 1 }
381424
},
382425
"items": [
383-
{ "type": "link", "url": "https://example.com/style.css", "shortName": "style.css", "responseEndMs": 450, "durationMs": 200, "sizeBytes": 45000 }
426+
{
427+
"type": "link",
428+
"url": "https://web.dev/style.css",
429+
"shortName": "style.css",
430+
"responseEndMs": 450,
431+
"durationMs": 200,
432+
"sizeBytes": 45000
433+
}
384434
]
385435
}
386436
```
387437
388438
#### Script-Loading
439+
389440
```json
390441
{
391442
"script": "Script-Loading",
@@ -399,7 +450,15 @@ If no interactions yet, `getINP()` returns `status: "error"` with `getDataFn: "g
399450
"thirdPartyBlockingCount": 1
400451
},
401452
"items": [
402-
{ "url": "https://example.com/app.js", "shortName": "app.js", "strategy": "blocking", "location": "head", "party": "first", "sizeBytes": 85000, "durationMs": 120 }
453+
{
454+
"url": "https://web.dev/app.js",
455+
"shortName": "app.js",
456+
"strategy": "blocking",
457+
"location": "head",
458+
"party": "first",
459+
"sizeBytes": 85000,
460+
"durationMs": 120
461+
}
403462
],
404463
"issues": [
405464
{ "severity": "error", "message": "2 blocking scripts in <head>" },
@@ -411,6 +470,7 @@ If no interactions yet, `getINP()` returns `status: "error"` with `getDataFn: "g
411470
### Interaction
412471
413472
#### Interactions (tracking)
473+
414474
```json
415475
{
416476
"script": "Interactions",
@@ -421,6 +481,7 @@ If no interactions yet, `getINP()` returns `status: "error"` with `getDataFn: "g
421481
```
422482
423483
#### Input-Latency-Breakdown (tracking)
484+
424485
```json
425486
{
426487
"script": "Input-Latency-Breakdown",
@@ -431,7 +492,9 @@ If no interactions yet, `getINP()` returns `status: "error"` with `getDataFn: "g
431492
```
432493
433494
#### Layout-Shift-Loading-and-Interaction
495+
434496
Immediately returns buffered CLS data, plus exposes summary function for ongoing tracking.
497+
435498
```json
436499
{
437500
"script": "Layout-Shift-Loading-and-Interaction",
@@ -453,7 +516,9 @@ Immediately returns buffered CLS data, plus exposes summary function for ongoing
453516
```
454517
455518
#### Long-Animation-Frames
519+
456520
Returns buffered LoAF data immediately. Ongoing tracking continues.
521+
457522
```json
458523
{
459524
"script": "Long-Animation-Frames",
@@ -471,7 +536,9 @@ Returns buffered LoAF data immediately. Ongoing tracking continues.
471536
```
472537
473538
#### Long-Animation-Frames-Script-Attribution
539+
474540
Returns buffered LoAF data immediately (do not wait for a timer):
541+
475542
```json
476543
{
477544
"script": "Long-Animation-Frames-Script-Attribution",
@@ -485,13 +552,12 @@ Returns buffered LoAF data immediately (do not wait for a timer):
485552
"framework": { "durationMs": 30, "count": 1 }
486553
}
487554
},
488-
"items": [
489-
{ "file": "app.js", "category": "first-party", "durationMs": 180, "count": 3 }
490-
]
555+
"items": [{ "file": "app.js", "category": "first-party", "durationMs": 180, "count": 3 }]
491556
}
492557
```
493558
494559
#### Scroll-Performance (tracking)
560+
495561
```json
496562
{
497563
"script": "Scroll-Performance",
@@ -510,7 +576,9 @@ Returns buffered LoAF data immediately (do not wait for a timer):
510576
```
511577
512578
#### LongTask
579+
513580
Returns buffered long tasks immediately. Ongoing tracking continues.
581+
514582
```json
515583
{
516584
"script": "LongTask",
@@ -529,6 +597,7 @@ Returns buffered long tasks immediately. Ongoing tracking continues.
529597
### Media
530598
531599
#### Image-Element-Audit (async)
600+
532601
```json
533602
{
534603
"script": "Image-Element-Audit",
@@ -567,32 +636,34 @@ Returns buffered long tasks immediately. Ongoing tracking continues.
567636
}
568637
],
569638
"issues": [
570-
{ "severity": "warning", "message": "img.thumbnail: Missing width/height attributes (CLS risk)" }
639+
{
640+
"severity": "warning",
641+
"message": "img.thumbnail: Missing width/height attributes (CLS risk)"
642+
}
571643
]
572644
}
573645
```
574646
575647
#### Video-Element-Audit
648+
576649
Same shape as Image-Element-Audit but for video elements.
577650
578651
#### SVG-Embedded-Bitmap-Analysis
652+
579653
```json
580654
{
581655
"script": "SVG-Embedded-Bitmap-Analysis",
582656
"status": "ok",
583657
"count": 2,
584-
"items": [
585-
{ "url": "icon.svg", "hasBitmap": true, "bitmapType": "image/png", "sizeBytes": 4500 }
586-
],
587-
"issues": [
588-
{ "severity": "warning", "message": "2 SVG files contain embedded bitmaps" }
589-
]
658+
"items": [{ "url": "icon.svg", "hasBitmap": true, "bitmapType": "image/png", "sizeBytes": 4500 }],
659+
"issues": [{ "severity": "warning", "message": "2 SVG files contain embedded bitmaps" }]
590660
}
591661
```
592662
593663
### Resources
594664
595665
#### Network-Bandwidth-Connection-Quality
666+
596667
```json
597668
{
598669
"script": "Network-Bandwidth-Connection-Quality",

0 commit comments

Comments
 (0)