Eric Allen | Web Vitals
Eric Allen | Web Vitals
Eric Allen | Web Vitals
a user-centric approach to UI performance metrics
Eric Allen | Web Vitals
a Google initiative started in May of 2020
Eric Allen | Web Vitals
three core measures (Core Vitals), designed to be an evolving set as the web matures
Eric Allen | Web Vitals
Eric Allen | Web Vitals
designed to measure loading, interactivity, and visual stability
Eric Allen | Web Vitals
evolving set of quality signals that should closely correlate to user experience
Eric Allen | Web Vitals
will likely be incorporated into Google's search algorithm
Eric Allen | Web Vitals
Largest Contentful Paint
measures loading
Eric Allen | Web Vitals
measures the largest image or block of text that is in the viewport
Eric Allen | Web Vitals
based on W3C Perf Working Group and Google research into First Meaningful Paint (FMP) and Speed Index (SI)
Eric Allen | Web Vitals
designed to replace measures like FMP, SI, First Contentful Paint (FCP), and onDOMContentLoaded
Eric Allen | Web Vitals
Eric Allen | Web Vitals
Largest Contentful Paint
should happen within 2.5 seconds
in the 75th percentile of page loads
Eric Allen | Web Vitals
Cumulative Layout Shift
measures visual stability
Eric Allen | Web Vitals
keeps track of when an element in the viewport changes its starting position
Eric Allen | Web Vitals
tries to only account for shifts not caused by user input
Eric Allen | Web Vitals
does not always represent something negative
Eric Allen | Web Vitals
Eric Allen | Web Vitals
Cumulative Layout Shift
should be less than 0.1
in the 75th percentile of page loads
Eric Allen | Web Vitals
First Input Delay
measures interactivity
Eric Allen | Web Vitals
measures time between the user interacting and the next time the main thread is free
Eric Allen | Web Vitals
designed to replace measures like Time to Interactive (TTI)
Eric Allen | Web Vitals
may not always be measured; replaced by Total Blocking Time (TBT) in lab setting
Eric Allen | Web Vitals
Eric Allen | Web Vitals
First Input Delay
should be less than 100 milliseconds
in the 75th percentile of page loads
Eric Allen | Web Vitals
Eric Allen | Web Vitals
First Contentful Paint / First Meaningful Paint
Eric Allen | Web Vitals
Total Blocking Time / Time to Interactive
Eric Allen | Web Vitals
Time to First Byte
Eric Allen | Web Vitals
Total Bytes Transferred to Client
Eric Allen | Web Vitals
Eric Allen | Web Vitals
measures what actual users are experiencing
Eric Allen | Web Vitals
synthetic tests can give a general sense of how things are going, but lack true insights into performance
Eric Allen | Web Vitals
simulated environments often don't load 3rd party content that can impact performance
Eric Allen | Web Vitals
Eric Allen | Web Vitals
Short Answer: Not yet
Eric Allen | Web Vitals
Long Answer: It tracks some more well-known performance measures like onDOMContentLoaded, FCP, TTI, etc., but we can make it track our Core Web Vitals, too
Eric Allen | Web Vitals
Note: It is important to take all of the available metrics into consideration when monitoring your app's performance. No one metric provides a full picture.
Eric Allen | Web Vitals
Eric Allen | Web Vitals
import {getCLS, getFID, getLCP} from 'web-vitals';
import { datadogRum } from "@datadog/browser-rum";
// we'll use this method to pass a custom Web Vital User Action
// to Datadog's RUM
const trackDatadogWebVital = (webVital) => {
// this will give us a good path for making custom metrics in Datadog
// with a path like @vital.CLS in our user actions
const vital = {
[webVital.name]: webVital,
};
// we'll trigger this as a User Action with the prefix `Web Vital:`
// to make it easier to find and identify our vitals in the logs
datadogRum.addUserAction(`Web Vital: ${webVital.name}`, { vital });
};
getCLS(trackDatadogWebVital);
getFID(trackDatadogWebVital);
getLCP(trackDatadogWebVital);
Eric Allen | Web Vitals
import { datadogRum } from "@datadog/browser-rum";
datadogRum.init({
applicationId: process.env.NEXT_PUBLIC_DATADOG_APPLICATION_ID,
clientToken: process.env.NEXT_PUBLIC_DATADOG_CLIENT_TOKEN,
site: 'datadoghq.com',
trackInteractions: true,
// https://github.com/DataDog/browser-sdk/blob/master/packages/rum/README.md#configuration
});
// Next.js looks for this method to be exported by your pages/_app.js
export function reportWebVitals(webVital) {
// this will give us a good path for making custom metrics in Datadog
// with a path like @vital.CLS in our user actions
const vital = {
[webVital.name]: webVital,
};
// we'll trigger this as a User Action with the prefix `Web Vital:`
// to make it easier to find and identify our vitals in the logs
datadogRum.addUserAction(`Web Vital: ${webVital.name}`, { vital });
}
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />;
}
export default MyApp;
Bonus: If you're using Next.js
Eric Allen | Web Vitals
Eric Allen | Web Vitals
Eric Allen | Web Vitals
Eric Allen | Web Vitals
Disclaimer: This is my first time using Datadog. There are probably better ways to achieve some of what we've done here.
Eric Allen | Web Vitals
Eric Allen | Web Vitals