Track Web Vitals
Grafana Cloud

Web Vitals

Web Vitals measure the real-world performance of your site so that developers, site owners, and others can improve it. For more information about Web Vitals, refer to web.dev.

The Web Vitals instrumentation uses the web-vitals package to collect and report data.

Tracking Web Vitals helps you to:

  • Analyze the loading times of your pages
  • Detect large repaints that take a lot of time
  • Detect delays until first inputs from your users

How to use the Web Vitals instrumentation

The following Web Vitals instrumentation is enabled by default. No additional configuration is required.

ts
initializeFaro({
  url: 'https://my-domain.my-tld/collect/{app-key}',
  app: {
    name: 'my-app',
  },
});

Note

If you overwrite the instrumentations array when you initialize the Grafana Faro Web SDK, you must manually include the Web Vitals instrumentation.

To manually include the Web Vitals instrumentation, use the following getWebInstrumentations helper function.

ts
initializeFaro({
  url: 'https://my-domain.my-tld/collect/{app-key}',
  app: {
    name: 'my-app',
  },
  instrumentations: [...getWebInstrumentations()],
});

Alternatively, if you want to fine-tune which instruments are enabled, you can use the following WebVitalsInstrumentation class.

ts
initializeFaro({
  url: 'https://my-domain.my-tld/collect/{app-key}',
  app: {
    name: 'my-app',
  },
  instrumentations: [new WebVitalsInstrumentation()],
});

How to capture Web Vitals attribution data

Web Vitals attribution data helps identify the elements and resources on a website that impact a specific web vital. By leveraging this data, you can find out what contributes to a bad web vital and reduce the time to repair by knowing where to look in your application.

Tracking attribution data is disabled by default. To enable it, set trackWebVitalsAttribution: true in the Faro configuration.

ts
initializeFaro({
  url: 'https://my-domain.my-tld/collect/{app-key}',
  app: {
    name: 'my-app',
  },
  instrumentations: [new WebVitalsInstrumentation()],
  trackWebVitalsAttribution: true,
});

How to capture all Web Vital changes

In most cases, you want to capture web vital values only when the metric is ready to be reported.

However, it’s possible to report every change by setting reportAllChanges to true. For example, you can track each larger layout shift as it happens. This feature can be useful when you are debugging, but in general it’s not necessary or recommended for measuring these metrics in production.

To capture all Web Vital changes, set reportAllChanges: true in the Faro configuration.

ts
initializeFaro({
  url: 'https://my-domain.my-tld/collect/{app-key}',
  app: {
    name: 'my-app',
  },
  instrumentations: [new WebVitalsInstrumentation()],
  webVitalsInstrumentation: {
    reportAllChanges: true,
  },
});

What data is included in each Web Vital measurement

Each measurement contains a metrics and a context object. The metrics object contains measured values whereas the context object contains all other attributes.

Each Web Vital measurement contains a set of standard metrics as described below. For information about the additional metrics and attributes of a specific Web Vital, refer to the respective sections.

Shared measurements and attributes

Metrics object:

  • ttfb|cls|fcp|lcp|fid|inp|: the value of the respective web vital metric
  • delta: This is the delta between the current and the last-reported value. The delta and cls are the same on the first report.

Context object (attributes):

  • id: the instance id of the metric
  • rating: Rating about the threshold the metric is in, which is either good, needs improvement, or poor
  • navigation_type: the type of navigation, which is navigate, reload, back-forward, back-forward-cache, prerender, or restore
  • navigation_entry_id: the unique id of the navigation entry emitted by Faro’s performance instrumentation

Cumulative Layout Shift (CLS)

Metrics object:

The following measurements and attributes are additionally attached to the CLS event.

  • largest_shift_value: CLS score of the first element (document order) that shifted when the largest layout shift occurred
  • largest_shift_time: the time when the largest layout shift occurred

Context object (attributes):

  • largest_shift_target: the selector identifying the first element (document order) that shifted when the largest layout shift occurred
  • load_state: loading state of the document, which is loading, dom-interactive, dom-content-loaded, or complete

First Contentful Paint (FCP)

The following measurements and attributes are additionally attached to the FCP event.

Metrics object:

  • first_byte_to_fcp: the delta between time to first byte (TTFB) and FCP
  • time_to_first_byte: the duration from making an HTTP request to the first byte received by the browser

Context object (attributes):

  • load_state: loading state of the document, which is loading, dom-interactive, dom-content-loaded, or complete

First Input Delay (FID)

The following measurements and attributes are additionally attached to the FID event.

Metrics object:

  • event_time: the time when the user interacted, which matches the timeStamp of the dispatched event

Context object (attributes):

  • event_target: the selector that identifies the element with which the user interacted. It is the target of the dispatched event.
  • event_type: the type of the event dispatched from the user interaction
  • load_state: loading state of the document. Which is loading, dom-interactive, dom-content-loaded, or complete

Interaction to Next Paint (INP)

The following measurements and attributes are additionally attached to the INP event.

Metrics object:

  • interaction_time: the time when the user first interacted during the frame where the INP candidate interaction occurred
  • presentation_delay: the time from when the browser finishes processing all event listeners for user interaction until the next frame presents on the screen
  • input_delay: the time from when the browser finishes processing event listeners for user interaction until the next frame displays on the screen
  • processing_duration: the time when the first event listener started running after a user interaction until when all event listener processing has been finished
  • next_paint_time: the best-guess timestamp of the next paint after the interaction

Context object (attributes):

  • load_state: loading state of the document, which is loading, dom-interactive, dom-content-loaded, or complete
  • interaction_target: the HTML element identified by interactionTarget
  • interaction_type: the type of interaction, based on the event type of the event, either pointer, or keyboard

Largest Contentful Paint (LCP)

The following measurements and attributes are additionally attached to the LCP event.

Metrics object:

  • element_render_delay: the delta between the LCP resource has finished loading and the LCP element has been fully rendered
  • resource_load_delay: the delta between TTFB and when the browser starts loading the LCP resource (otherwise 0)
  • resource_load_duration: the time it takes to load the LCP resource (0 if there is none)

Context object (attributes):

  • element: the largest contentful paint element itself

Time to First Byte (TTFB)

The following measurements and attributes are additionally attached to the TTFB event.

  • dns_duration: the time to resolve the DNS for the requested domain
  • connection_duration: the time to create the connection
  • request_duration: the time between when the request was sent until the first byte of the response was received
  • waiting_duration: the time from user initiation to request handling start
  • cache_duration: the time spent checking the HTTP cache

Context object (attributes): No additional attributes.