export interface PerformanceBudgets { routeJsBytes?: number; routeCssBytes?: number; htmlBytes?: number; imageBytes?: number; hydrationMs?: number; serverRenderMs?: number; } export interface PerformanceMeasurement { routeJsBytes?: number; routeCssBytes?: number; htmlBytes?: number; imageBytes?: number; hydrationMs?: number; serverRenderMs?: number; } export interface BudgetViolation { metric: keyof PerformanceBudgets; budget: number; actual: number; overBy: number; } export function checkPerformanceBudgets( budgets: PerformanceBudgets, measurement: PerformanceMeasurement, ): BudgetViolation[] { const violations: BudgetViolation[] = []; for (const metric of Object.keys(budgets) as Array) { const budget = budgets[metric]; const actual = measurement[metric]; if (budget === undefined || actual === undefined || actual <= budget) continue; violations.push({ metric, budget, actual, overBy: actual - budget }); } return violations; }