import { onCLS, onINP, onLCP } from "web-vitals";
function send(metric) {
const body = JSON.stringify({
name: metric.name, value: metric.value, rating: metric.rating, id: metric.id,
});
navigator.sendBeacon("/analytics", body);
}
onCLS(send);
onINP(send);
onLCP(send);
Use the web-vitals library in the page, and send each metric to your server with navigator.sendBeacon. PerformanceObserver is the browser API underneath it.
What the code does:
- The
web-vitalslibrary measures LCP, INP and CLS the same way Chrome does. These are the loading, responsiveness and layout-shift metrics. - It calls your callback with each metric's name, value and rating.
- Some metrics are only final when the page is hidden. The library reports them at the right moment.
navigator.sendBeaconqueues a small POST request that still gets sent after the page unloads. A normalfetchmight be cancelled.- On the server, you group the data by page and device, and look at the 75th percentile.
PerformanceObserver is what the library uses inside. It subscribes to performance entries as the browser records them. Entry types include:
largest-contentful-paint,layout-shiftandeventlongtask,resourceandnavigation- your own
markandmeasureentries
You can use it directly for custom metrics. For example, time a key interaction with performance.mark and performance.measure. Pass buffered: true to also get entries that were recorded before you subscribed.
- The
web-vitalslibrary measures metrics the same way Chrome does. - Report when the page is hidden, because
sendBeaconstill sends after the page unloads. - Look at the 75th percentile, and group the data by page and device.
PerformanceObserversubscribes to performance entry types.- Use
performance.markandperformance.measurefor custom metrics.