InteractionContentfulPaint

The InteractionContentfulPaint interface provides timing information about contentful paints attributable to an interaction.

Instance properties

This interface directly defines the following properties:

InteractionContentfulPaint.interactionId Read only

The id of the interaction that resulted in the paint.

InteractionContentfulPaint.largestContentfulPaint Read only

Returns details of the largest LargestContentfulPaint for the interaction. This can remain the same between two InteractionContentfulPaint entries for the same interaction if a new contentful paint is smaller than the current largest contentful paint for that interaction.

InteractionContentfulPaint.navigationId Read only

The id of the navigation this paint is attributable to.

InteractionContentfulPaint.paintTime Read only

Returns the timestamp of when the first rendering phase ended and the paint phase started.

InteractionContentfulPaint.presentationTime Read only

Returns the timestamp of when the first painted pixels were actually drawn on the screen.

It also extends the following PerformanceEntry properties, qualifying and constraining them as described:

PerformanceEntry.entryType Read only

Returns "interaction-contentful-paint".

PerformanceEntry.duration Read only

Returns the result of InteractionContentfulPaint.presentationTime - PerformanceEntry.startTime.

PerformanceEntry.name Read only

Always returns an empty string.

PerformanceEntry.startTime Read only

Returns the timestamp of the interaction that resulted in the soft navigation.

Description

The InteractionContentfulPaint provides a stream of paint updates attributable to an interaction.

At present this is scoped to increasing paint sizes, so it can be used to measure Largest Contentful Paint (LCP) for Soft Navigations, but the API has been designed to allow for all paints relevant to an interaction to be emitted.

InteractionContentfulPaint is needed instead of using the LargestContentfulPaint API as that is only emitted per full page load and is finalized upon interaction (which is a necessary start to a soft navigation).

Relationship with Event Timing and INP

The Event Timing API API provides details about UIEvents — scheduling and processing durations, and total duration to next paint — but does not actually directly track the effects of those events, nor any future paints those effects might cause. It is intended to measure the responsiveness time during which a user receives no feedback, which should be kept to a minimum and forms the basis for metrics such as Interaction to Next Paint (INP).

InteractionContentfulPaint, despite being similarly named to Interaction to Next Paint, serves a different purpose. InteractionContentfulPaint excludes non-contentful paints which do count for Event Timing and INP but also measures additional paints beyond the first paint. It allows enables measurement of a more complete understanding of the effects and content updates directly attributable to an interaction.

Examples

Observing interaction contentful paints

In the following example, a PerformanceObserver is registered to get the soft navigations. The buffered flag is used to access data from before observer creation.

js
const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    console.log("Interaction Contentful Paints:", entry.startTime, entry);
  }
});
observer.observe({ type: "interaction-contentful-paints", buffered: true });

Observing interaction contentful paints specific to a soft navigation

One of the key uses of the InteractionContentfulPaint interface is to measure all contentful paints related to a soft navigation to calculate the Largest Contentful Paint (LCP) for that soft navigation.

To do this, it is recommended to use the PerformanceSoftNavigation.interactionId rather than the PerformanceSoftNavigation.navigationId, since some LCP candidates can happen before the soft navigation is defined (for paints, before the URL is updated) and will therefore have the old navigationId.

js
let currentNavigationInteractionId = 1045; // hardcoded in this example

const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (entry.InteractionId === currentNavigationInteractionId) {
      console.log("Soft LCP candidate:", entry.startTime, entry);
    }
  }
});
observer.observe({ type: "interaction-contentful-paints", buffered: true });

Specifications

This feature does not appear to be defined in any specification.

Browser compatibility

See also