Vì Lighthouse là lab data: một lần chạy, một thiết bị mô phỏng, mạng mô phỏng, không cache, không extension. Người dùng thật thì đủ loại máy, mạng 3G, tab chạy nền. Cái quyết định xếp hạng là field data — số liệu thu từ người dùng thật.
Next.js có sẵn hook để bắt số liệu đó ngay trong app:
tsx
'use client'
import { useReportWebVitals } from 'next/web-vitals'
export function WebVitals() {
useReportWebVitals((metric) => {
navigator.sendBeacon('/api/vitals', JSON.stringify({
name: metric.name, // LCP | CLS | INP | FCP | TTFB
value: metric.value,
id: metric.id,
path: window.location.pathname,
}))
})
return null
}Đặt component này trong root layout. Dùng sendBeacon để dữ liệu vẫn gửi được khi người dùng đóng tab.
Đọc số liệu cho đúng: luôn nhìn phân vị 75 chứ không phải trung bình — trung bình bị nhóm máy mạnh kéo xuống đẹp trong khi 25% người dùng vẫn chậm. Chia theo route và theo loại thiết bị, vì thường chỉ một vài trang cụ thể có vấn đề.
Ngưỡng "tốt": LCP dưới 2.5s, CLS dưới 0.1, INP dưới 200ms.