/** * @file Enhanced Vitals Collector * @description Extended Core Web Vitals collection with advanced attribution, * custom metrics, and detailed analysis. * * Features: * - Core Web Vitals (LCP, FID, CLS, INP, FCP, TTFB) * - Custom metric definitions * - Attribution analysis * - Element-level tracking * - Historical comparison * - Threshold management */ /** * Metric name type */ export type MetricName = 'LCP' | 'FID' | 'CLS' | 'INP' | 'FCP' | 'TTFB' | 'FMP' | 'TTI' | 'TBT' | 'custom'; /** * Metric rating */ export type MetricRating = 'good' | 'needs-improvement' | 'poor'; /** * Collected metric data */ export interface CollectedMetric { name: MetricName | string; value: number; rating: MetricRating; delta: number; id: string; navigationType: string; timestamp: number; attribution: MetricAttribution | null; entries: PerformanceEntry[]; } /** * Metric attribution data */ export interface MetricAttribution { element?: string; url?: string; timeToFirstByte?: number; resourceLoadDelay?: number; elementRenderDelay?: number; lcpResourceEntry?: PerformanceResourceTiming; largestShiftTarget?: string; largestShiftTime?: number; loadState?: string; eventTarget?: string; eventType?: string; eventTime?: number; nextPaintTime?: number; } /** * Metric thresholds */ export interface MetricThresholds { good: number; poor: number; } /** * Collection configuration */ export interface VitalsCollectionConfig { /** Enable collection */ enabled: boolean; /** Metrics to collect */ metrics: MetricName[]; /** Custom thresholds */ thresholds?: Partial>; /** Enable attribution */ attribution: boolean; /** Sample rate (0-1) */ sampleRate: number; /** Report endpoint */ reportEndpoint?: string; /** Batch reports */ batchReports: boolean; /** Batch interval in ms */ batchInterval: number; /** Debug mode */ debug: boolean; } /** * Metric callback */ export type MetricCallback = (metric: CollectedMetric) => void; /** * Default thresholds based on Google recommendations */ export declare const DEFAULT_THRESHOLDS: Record; /** * Enhanced vitals collection with attribution */ export declare class EnhancedVitalsCollector { private config; private thresholds; private metrics; private callbacks; private reportBuffer; private flushTimer; private observers; private isInitialized; constructor(config?: Partial); /** * Initialize vitals collection */ init(): () => void; /** * Subscribe to metric updates */ subscribe(callback: MetricCallback): () => void; /** * Get all collected metrics */ getMetrics(): Map; /** * Get specific metric */ getMetric(name: MetricName): CollectedMetric[]; /** * Get latest value for a metric */ getLatestValue(name: MetricName): CollectedMetric | null; /** * Track a custom metric */ trackCustomMetric(name: string, value: number, thresholds?: MetricThresholds): void; /** * Start a custom timing */ startTiming(name: string): () => void; /** * Flush any pending reports */ flush(): void; /** * Get summary statistics */ getSummary(): Record; /** * Calculate overall performance score */ calculateScore(): number; private setupMetricCollection; private observeLCP; private observeFID; private observeCLS; private observeINP; private observeFCP; private observeTTFB; private recordMetric; private calculateRating; private ratingToScore; private getElementSelector; private getNavigationType; private setupLifecycleHandlers; private startBatchFlush; /** * Send collected metrics to the reporting endpoint. * * Note: This method intentionally uses raw fetch/sendBeacon because: * 1. Web Vitals reporting should be independent of the main API client * 2. Uses keepalive/sendBeacon for reliability when page is unloading * 3. Reporting endpoints are often third-party analytics services * * @see {@link @/lib/api/api-client} for application API calls */ private sendToEndpoint; private cleanup; private generateId; private log; } /** * Get or create the global vitals collector */ export declare function getEnhancedVitalsCollector(config?: Partial): EnhancedVitalsCollector; /** * Reset the collector instance */ export declare function resetEnhancedVitalsCollector(): void;