InteractionContentfulPaint
The InteractionContentfulPaint interface provides timing information about contentful paints attributable to an interaction.
Instance properties
This interface directly defines the following properties:
InteractionContentfulPaint.interactionIdRead only-
The id of the interaction that resulted in the paint.
InteractionContentfulPaint.largestContentfulPaintRead only-
Returns details of the largest
LargestContentfulPaintfor the interaction. This can remain the same between twoInteractionContentfulPaintentries for the same interaction if a new contentful paint is smaller than the current largest contentful paint for that interaction. -
The id of the navigation this paint is attributable to.
InteractionContentfulPaint.paintTimeRead only-
Returns the
timestampof when the first rendering phase ended and the paint phase started. InteractionContentfulPaint.presentationTimeRead only-
Returns the
timestampof 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.entryTypeRead only-
Returns
"interaction-contentful-paint". PerformanceEntry.durationRead only-
Returns the result of
InteractionContentfulPaint.presentationTime-PerformanceEntry.startTime. PerformanceEntry.nameRead only-
Always returns an empty string.
PerformanceEntry.startTimeRead only-
Returns the
timestampof 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.
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.
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
- Measuring soft navigations on developer.chrome.com (2026)