PerformanceObserver

PerformanceObserver streams timeline entries as they are recorded, replacing polling of performance.getEntries(). Pass entryTypes, or one type with buffered: true to get earlier entries too; PerformanceObserver.supportedEntryTypes lists 15 in Chrome 152 1 .

LCP and User Timing entries as they happenHTMLLive
<h1>Quarterly report</h1>
<script>
  new PerformanceObserver((list) => list.getEntries().forEach((e) => console.log(e.entryType,
    e.name || e.element.localName, Math.round(e.startTime), Math.round(e.duration))))
    .observe({ entryTypes: ['largest-contentful-paint', 'mark', 'measure'] });
  performance.mark('build-start');
  for (let i = 0, sum = 0; i < 3e7; i++) sum += i;  // slow work
  performance.measure('build-report', 'build-start');
</script>

The blocking loop pushed LCP back. The old performance.timing is deprecated in favor of the navigation entry; Core Web Vitals covers Web Vitals.