Overview
The Performance API in JavaScript provides a set of standards for measuring and evaluating performance metrics. It acts as a comprehensive tool for reporting on Core Web Vitals and other performance statistics directly within the DOM, similar to many performance testing tools.
Browser Support
While the majority of the Performance API is supported by major browsers, full support for Core Web Vitals properties is limited to Chromium-based browsers. Firefox supports some of these properties, like First Contentful Paint (FCP) and Largest Contentful Paint (LCP). For comprehensive metrics, using Chrome is recommended.
Retrieving Performance Metrics
You can access performance metrics via two primary methods:
-
performance.getEntries()
: Returns the complete list of entries recorded since the page started. -
PerformanceObserver
: Observes and dispatches performance metrics asynchronously, which can be more efficient.
Using PerformanceObserver
Here’s an example of setting up a PerformanceObserver
for the LCP metric:
const lcpObserver = new PerformanceObserver(list => {
const entries = list.getEntries();
const lcp = entries[entries.length - 1];
console.log(`LCP element:`, lcp.element);
console.log(`Time to render: ${lcp.startTime} milliseconds`);
});
lcpObserver.observe({ type: "largest-contentful-paint", buffered: true });
Reporting Other Core Web Vitals
First Contentful Paint (FCP)
FCP measures the time it takes for the first piece of DOM content to be rendered. Here’s how you can observe it:
const paintObserver = new PerformanceObserver(list => {
list.getEntries().forEach(entry => {
console.log(`Time to ${entry.name} took ${entry.startTime} milliseconds`);
});
});
paintObserver.observe({ type: "paint", buffered: true });
Cumulative Layout Shift (CLS)
CLS measures the visual stability of a page. Here’s an example of observing layout shifts:
const observer = new PerformanceObserver(list => {
let cumulativeLayoutShift = 0;
list.getEntries().forEach(entry => {
if (!entry.hadRecentInput) {
cumulativeLayoutShift += entry.value;
}
console.log({ entry, cumulativeLayoutShift });
});
});
observer.observe({ type: "layout-shift", buffered: true });
Interaction to Next Paint (INP)
INP measures the responsiveness of a page to user interactions. Here’s an example of observing INP:
const observer = new PerformanceObserver(list => {
list.getEntries().forEach(entry => {
const duration = entry.duration;
const delay = entry.processingStart - entry.startTime;
if (!entry.cancelable) {
console.log(`INP Duration: ${duration}`);
console.log(`INP Delay: ${delay}`);
}
});
});
observer.observe({ type: "event", buffered: true });
Long Animation Frames (LoAFs)
Long Animation Frames identify frames that take too long to render. Here’s how you can observe these frames:
const observer = new PerformanceObserver(list => {
list.getEntries().forEach(entry => {
if (entry.duration > 50) {
console.log(`Frame took ${entry.duration} ms`);
console.log(`Contributing scripts:`);
entry.scripts.forEach(script => {
console.table({
sourceURL: script.sourceURL,
duration: script.duration,
functionName: script.sourceFunctionName,
invoker: script.invoker
});
});
}
});
});
observer.observe({ type: "long-animation-frame", buffered: true });
Using Libraries
For easier handling of Core Web Vitals, you can use the web-vitals
library:
import { getINP } from 'web-vitals';
getINP(info => {
console.log(info);
}, { reportAllChanges: true });
Monitoring Performance
While measuring performance is essential, continuous monitoring provides deeper insights. Tools like DebugBear offer comprehensive monitoring, including metrics, historical data, and real-time performance insights. They can help identify slow interactions, layout shifts, and key performance bottlenecks.
Top comments (0)