# ABE — Performance Metrics Specification ## Concepto Durante la exploración, ABE captura métricas de rendimiento de cada estado visitado. Inspirado en Checkly y Datadog RUM. Esto permite detectar anomalías de rendimiento además de errores funcionales. ## Métricas capturadas por estado ```typescript interface IPerformanceMetrics { stateId: string; url: string; timestamp: number; // Navigation Timing (disponibles via Playwright) ttfb: number; // Time to First Byte (ms) domContentLoaded: number; // DOMContentLoaded event (ms) loadComplete: number; // Load event (ms) // Core Web Vitals (via web-vitals library injected) lcp: number | null; // Largest Contentful Paint (ms) cls: number | null; // Cumulative Layout Shift (score) fid: number | null; // First Input Delay (ms) - solo tras interacción inp: number | null; // Interaction to Next Paint (ms) // Resource counts totalRequests: number; failedRequests: number; totalTransferSize: number; // bytes } ``` ## Implementación ### TTFB, DOMContentLoaded, Load Via `page.evaluate()` usando `performance.timing` después de navigation: ```typescript const timing = await page.evaluate(() => ({ ttfb: performance.timing.responseStart - performance.timing.requestStart, domContentLoaded: performance.timing.domContentLoadedEventEnd - performance.timing.navigationStart, loadComplete: performance.timing.loadEventEnd - performance.timing.navigationStart, })); ``` ### Core Web Vitals Inyectar el script de `web-vitals` (npm) en la página: ```typescript await page.addScriptTag({ url: 'https://unpkg.com/web-vitals/dist/web-vitals.iife.js' }); const vitals = await page.evaluate(() => new Promise(resolve => { const result = {}; webVitals.getLCP(m => result.lcp = m.value); webVitals.getCLS(m => result.cls = m.value); webVitals.getINP(m => result.inp = m.value); setTimeout(() => resolve(result), 3000); // wait 3s for vitals })); ``` ## Anomalías de rendimiento (nuevos tipos) Añadir al AnomalyDetector con umbrales basados en Core Web Vitals de Google: | Métrica | Good | Needs Improvement | Poor (anomalía) | |---------|---------|-------------------|-----------------| | LCP | <2500ms | 2500-4000ms | >4000ms → high | | CLS | <0.1 | 0.1-0.25 | >0.25 → medium | | INP | <200ms | 200-500ms | >500ms → high | | TTFB | <800ms | 800-1800ms | >1800ms → medium| Tipo de anomalía: `performance_degradation` ## Modelo de datos — añadir a SQLite ### Table: performance_metrics ```sql CREATE TABLE IF NOT EXISTS performance_metrics ( id TEXT PRIMARY KEY, session_id TEXT NOT NULL, state_id TEXT NOT NULL, url TEXT NOT NULL, ttfb INTEGER, dom_content_loaded INTEGER, load_complete INTEGER, lcp INTEGER, cls REAL, fid INTEGER, inp INTEGER, total_requests INTEGER, failed_requests INTEGER, total_transfer_size INTEGER, captured_at INTEGER NOT NULL ); ``` ## Frontend — Performance tab Añadir tab "Performance" en SessionDetail: - Tabla con todos los estados visitados y sus métricas - Columnas con color coded: verde/amarillo/rojo según umbrales de Google - Gráfico de barras: LCP por estado (para identificar páginas lentas) - Summary cards: peor LCP, peor CLS, peor TTFB de la sesión ## En el bug report Si hay anomalía performance_degradation, añadir sección en report.md: ``` ## Performance Issue - LCP: 5200ms (threshold: 4000ms) ❌ - CLS: 0.08 ✅ - TTFB: 2100ms (threshold: 1800ms) ❌ - Total page size: 4.2MB ``` ## Configuración Añadir a ExplorationConfig: ```typescript performance: { enabled: boolean; // default: true lcpThresholdMs: number; // default: 4000 clsThreshold: number; // default: 0.25 inpThresholdMs: number; // default: 500 ttfbThresholdMs: number; // default: 1800 } ```