Monitoring

Web Vitals w/ Datadog RUM

Eric Allen | Web Vitals

  1. What are Web Vitals?
  2. How are they different from previous performance measures?
  3. What can we track with Datadog?
  4. Q&A

Our Journey

Eric Allen | Web Vitals

What are 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

Core 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

LCP

 

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

Metric

 

Largest Contentful Paint

should happen within 2.5 seconds

in the 75th percentile of page loads

Eric Allen | Web Vitals

CLS

 

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

Metric

 

Cumulative Layout Shift

should be less than 0.1

in the 75th percentile of page loads

Eric Allen | Web Vitals

FID

 

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

Metric

 

First Input Delay

should be less than 100 milliseconds

in the 75th percentile of page loads

Eric Allen | Web Vitals

Other

Performance

Measures

Eric Allen | Web Vitals

First Contentful Paint / First Meaningful Paint

FCP / FMP

Eric Allen | Web Vitals

Total Blocking Time / Time to Interactive

TBT / TTI

Eric Allen | Web Vitals

Time to First Byte

TTFB

Eric Allen | Web Vitals

Total Bytes Transferred to Client

Page Weight

Eric Allen | Web Vitals

Why RUM Measures Matter

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

Does Datadog Track

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

Tracking w/ Datadog

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

Viewing in Datadog

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

Q&A

Eric Allen | Web Vitals