@@ -12,11 +12,29 @@ import type {
1212import { compactJson } from '../utils/compactJson' ;
1313import log from '../utils/log' ;
1414
15+ /**
16+ * Default threshold for Long Tasks detector.
17+ * Used when detector is enabled without a valid custom threshold.
18+ */
1519export const DEFAULT_LONG_TASK_THRESHOLD_MS = 70 ;
20+ /**
21+ * Default threshold for Long Animation Frames detector.
22+ * Used when detector is enabled without a valid custom threshold.
23+ */
1624export const DEFAULT_LOAF_THRESHOLD_MS = 200 ;
25+ /**
26+ * Global minimum threshold guard for freeze detectors.
27+ * Prevents overly aggressive configuration and event spam.
28+ */
1729export const MIN_ISSUE_THRESHOLD_MS = 50 ;
30+ /**
31+ * Maximum waiting time for Web Vitals aggregation before forced report attempt.
32+ */
1833export const WEB_VITALS_REPORT_TIMEOUT_MS = 10000 ;
1934
35+ /**
36+ * Web Vitals "good/poor" boundaries used to enrich issue summaries.
37+ */
2038const METRIC_THRESHOLDS : Record < string , [ good : number , poor : number ] > = {
2139 LCP : [ 2500 , 4000 ] ,
2240 FCP : [ 1800 , 3000 ] ,
@@ -25,6 +43,10 @@ const METRIC_THRESHOLDS: Record<string, [good: number, poor: number]> = {
2543 CLS : [ 0.1 , 0.25 ] ,
2644} ;
2745
46+ /**
47+ * Number of Core Web Vitals currently collected by this monitor.
48+ * We wait for all metrics first, then fallback to timeout/pagehide flush.
49+ */
2850const TOTAL_WEB_VITALS = 5 ;
2951
3052/**
@@ -34,10 +56,15 @@ const TOTAL_WEB_VITALS = 5;
3456 * - Aggregated Web Vitals report
3557 */
3658export class PerformanceIssuesMonitor {
59+ /** Active observer for Long Tasks API. */
3760 private longTaskObserver : PerformanceObserver | null = null ;
61+ /** Active observer for Long Animation Frames API. */
3862 private loafObserver : PerformanceObserver | null = null ;
63+ /** Cleanup hook for Web Vitals timeout/pagehide listeners. */
3964 private webVitalsCleanup : ( ( ) => void ) | null = null ;
65+ /** Prevents duplicate initialization and duplicate issue streams. */
4066 private isInitialized = false ;
67+ /** Marks monitor as stopped to ignore async callbacks after destroy. */
4168 private destroyed = false ;
4269
4370 /**
@@ -75,6 +102,9 @@ export class PerformanceIssuesMonitor {
75102
76103 /**
77104 * Cleanup active observers.
105+ *
106+ * `isInitialized` controls re-initialization guard.
107+ * `destroyed` prevents any late async callback from emitting issues.
78108 */
79109 public destroy ( ) : void {
80110 this . destroyed = true ;
@@ -88,6 +118,7 @@ export class PerformanceIssuesMonitor {
88118 }
89119
90120 /**
121+ * Observe Long Tasks and emit performance issues above threshold.
91122 *
92123 * @param thresholdMs max allowed duration
93124 * @param onIssue issue callback
@@ -138,6 +169,7 @@ export class PerformanceIssuesMonitor {
138169 }
139170
140171 /**
172+ * Observe Long Animation Frames and emit performance issues above threshold.
141173 *
142174 * @param thresholdMs max allowed duration
143175 * @param onIssue issue callback
@@ -211,6 +243,8 @@ export class PerformanceIssuesMonitor {
211243 }
212244
213245 /**
246+ * Observe Web Vitals and emit a single aggregated poor report.
247+ * Reports when all metrics are collected or on timeout/pagehide fallback.
214248 *
215249 * @param onIssue issue callback
216250 */
@@ -225,6 +259,9 @@ export class PerformanceIssuesMonitor {
225259 let timeoutId : ReturnType < typeof setTimeout > | null = null ;
226260 let handlePageHide : ( ( ) => void ) | null = null ;
227261
262+ /**
263+ * Clears timeout and page lifecycle listener bound for this monitor run.
264+ */
228265 const cleanup = ( ) : void => {
229266 if ( timeoutId !== null ) {
230267 clearTimeout ( timeoutId ) ;
@@ -236,6 +273,11 @@ export class PerformanceIssuesMonitor {
236273 }
237274 } ;
238275
276+ /**
277+ * Tries to emit an aggregated Web Vitals issue.
278+ * When `force` is false, waits for all vitals.
279+ * When `force` is true, emits with currently collected metrics.
280+ */
239281 const tryReport = ( force : boolean ) : void => {
240282 if ( this . destroyed || reported ) {
241283 return ;
@@ -283,6 +325,9 @@ export class PerformanceIssuesMonitor {
283325 } ) ;
284326 } ;
285327
328+ /**
329+ * Collects latest metric snapshot per metric name.
330+ */
286331 const collect = ( metric : { name : string ; value : number ; rating : WebVitalRating ; delta : number } ) : void => {
287332 if ( this . destroyed || reported ) {
288333 return ;
@@ -327,6 +372,8 @@ export class PerformanceIssuesMonitor {
327372}
328373
329374/**
375+ * Checks if browser supports a performance entry type.
376+ *
330377 *
331378 * @param type performance entry type
332379 */
@@ -343,6 +390,8 @@ function supportsEntryType(type: string): boolean {
343390}
344391
345392/**
393+ * Resolves threshold from user input and applies global minimum clamp.
394+ *
346395 *
347396 * @param value custom threshold
348397 * @param fallback default threshold
@@ -356,8 +405,11 @@ function resolveThreshold(value: number | undefined, fallback: number): number {
356405}
357406
358407/**
408+ * Returns custom threshold from detector config object.
409+ * Boolean options use default threshold.
359410 *
360- * @param value
411+ *
412+ * @param value detector config value
361413 */
362414function resolveThresholdOption ( value : boolean | { thresholdMs ?: number } ) : number | undefined {
363415 if ( typeof value === 'object' && value !== null ) {
@@ -368,6 +420,8 @@ function resolveThresholdOption(value: boolean | { thresholdMs?: number }): numb
368420}
369421
370422/**
423+ * Formats Web Vitals metric value for readable summary.
424+ *
371425 *
372426 * @param name metric name
373427 * @param value metric value
@@ -377,6 +431,8 @@ function formatValue(name: string, value: number): string {
377431}
378432
379433/**
434+ * Serializes LoAF script timing into compact JSON payload.
435+ *
380436 *
381437 * @param script loaf script entry
382438 */
@@ -396,6 +452,8 @@ function serializeScript(script: LoAFScript): Json {
396452}
397453
398454/**
455+ * Serializes aggregated Web Vitals report into event context payload.
456+ *
399457 *
400458 * @param report aggregated vitals report
401459 */
0 commit comments