@@ -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` ` `
1461541. evaluate_script (INP .js ) → { status: " tracking" , getDataFn: " getINP" }
1471552. (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+
189199Returns 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+
231247If 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+
434496Immediately 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+
456520Returns 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+
474540Returns 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+
513580Returns 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+
576649Same 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