CodePark/ questions / Measuring performance
START PRACTICINGPRACTICE
Frontend question · Browser & web performance › Measuring performance

How would you collect Core Web Vitals from real users? Explain what this code does and what PerformanceObserver gives you.

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-vitals library 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.sendBeacon queues a small POST request that still gets sent after the page unloads. A normal fetch might 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-shift and event
  • longtask, resource and navigation
  • your own mark and measure entries

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-vitals library measures metrics the same way Chrome does.
  • Report when the page is hidden, because sendBeacon still sends after the page unloads.
  • Look at the 75th percentile, and group the data by page and device.
  • PerformanceObserver subscribes to performance entry types.
  • Use performance.mark and performance.measure for custom metrics.