import { NextResponse } from "next/server"; /** * Web Vitals 上报端点 * * 接收前端 navigator.sendBeacon 上报的 LCP/CLS/INP/FCP/TTFP 指标, * 当前实现:写入服务端日志(便于开发期查看),生产可接入监控系统。 * * 性能预算基线(见 docs/architecture/audit/performance-budget-audit-report.md): * - LCP ≤ 2.5s,INP ≤ 200ms,CLS ≤ 0.05,TTFB ≤ 800ms,FCP ≤ 1.8s * - 超出预算的 "poor" 级别会以 warn 级别日志记录便于排查 */ export const runtime = "edge"; type WebVitalEntry = { name: string; startTime: number; duration: number; entryType: string; }; type WebVitalsPayload = { id: string; name: string; value: number; rating: "good" | "needs-improvement" | "poor"; delta: number; entries: WebVitalEntry[]; path: string; timestamp: number; }; // 性能预算基线,超出即标记为 poor const BUDGETS: Record = { LCP: 2500, INP: 200, CLS: 0.05, FCP: 1800, TTFB: 800, }; export async function POST(request: Request): Promise { let payload: WebVitalsPayload; try { payload = (await request.json()) as WebVitalsPayload; } catch { return NextResponse.json({ ok: false }, { status: 400 }); } const budget = BUDGETS[payload.name]; const isOverBudget = budget !== undefined && payload.value > budget; // good/info 级别用 info,rating poor 或超预算用 warn if (payload.rating === "poor" || isOverBudget) { console.warn("[web-vitals] over-budget", { name: payload.name, value: payload.value, rating: payload.rating, budget, path: payload.path, id: payload.id, }); } else { console.info("[web-vitals] reported", { name: payload.name, value: payload.value, rating: payload.rating, path: payload.path, }); } return NextResponse.json({ ok: true }); }