Soft Navigations and Interaction Contentful Paint

Draft Community Group Report,

This version:
https://wicg.github.io/soft-navigations/
Test Suite:
https://github.com/web-platform-tests/wpt/tree/master/soft-navigation-heuristics
Issue Tracking:
GitHub
Inline In Spec
Editors:
(Google)
(Google)
Former Editor:
(Shopify)

Abstract

This document defines a set of APIs that web page authors can use to detect same-document ("soft") navigations and attribute subsequent page modifications and contentful paints back to the user interactions that triggered them.

Status of this document

This specification was published by the Web Platform Incubator Community Group. It is not a W3C Standard nor is it on the W3C Standards Track. Please note that under the W3C Community Contributor License Agreement (CLA) there is a limited opt-out and other conditions apply. Learn more about W3C Community and Business Groups.

1. Introduction

This section is non-normative.

Modern web applications often dynamically update content in response to user interactions without performing a full page navigation. These interaction-initiated effects—such as structural DOM modifications, contentful paints, and history state changes—have historically been difficult to measure and attribute to the correct user actions.

Consider a typical Single Page Application pattern: a user clicks a product link, which triggers a click event handler. This handler initiates a network fetch() for product details. When the response arrives, a callback is executed that dynamically injects the new content into the DOM and uses the History or Navigation API to update the URL. While this appears to the user as a navigation, existing metrics like Largest Contentful Paint (LCP) ([LARGEST-CONTENTFUL-PAINT]) only measure the initial page load, and Interaction to Next Paint (INP) only measures the immediate visual feedback of the click itself, leaving the significant subsequent rendering and "soft" navigation uncaptured.

This specification leverages the [EVENT-TIMING] API to define interactions and the [ASYNC-CONTEXT] proposal to track causality across asynchronous task boundaries, mapping modified DOM nodes to interactions, enabling attribution of contentful paints to interactions that caused them. It defines how browsers can identify and report these effects, including "Soft Navigations," by integrating with [PAINT-TIMING] and [LARGEST-CONTENTFUL-PAINT] to attribute rendering changes to the performance timeline.

2. Performance Timeline Slicing

This section is non-normative.

To attribute performance metrics (such as event timings, layout shifts, resource loads, or long animation frames) to their initiating navigation, the performance timeline is sliced into segments using a navigationId attribute on PerformanceEntry.

Determining the exact slice point for a transition that spans time is complex. To ensure consistent attribution, this specification adopts a model where the timeline is not sliced immediately upon every URL modification; instead, the transition is deferred until a soft navigation is ready to be emitted to the performance timeline.

For a detailed discussion of the design trade-offs, attribution rules, and edge cases, see the [PERFORMANCE-TIMELINE] issue comment.

2.1. Navigation ID

A navigation id is a unique identifier assigned to each navigation (both hard and soft) within a global object’s lifetime.

Each Window has:

Note: The initial navigation id value and navigation id increment are used to calculate navigationId values (see increment the current navigation id). This discourages developers from relying on it to count the exact number of navigations or assuming it starts at zero. User agents are expected not to use shared global navigation values across different Window objects to prevent cross-origin leaks.

To increment the current navigation id given a Window window:
  1. Set window’s navigation count to window’s navigation count plus 1.

  2. Let newId be window’s initial navigation id value plus (window’s navigation count times window’s navigation id increment).

  3. Set window’s current navigation id to newId.

2.2. The PerformanceEntry extension

[Exposed=(Window,Worker)]
partial interface PerformanceEntry {
    readonly attribute unsigned long long navigationId;
};
Each PerformanceEntry has an associated navigation id, a 64-bit unsigned integer, initially 0.

The navigationId attribute’s getter must return this’s navigation id.

2.3. Performance Timeline Integration

In queue a PerformanceEntry, after step 1 (initializing the entry), add the following steps:

  1. If newEntry’s navigation id is 0:

    1. If global is a Window object:

      1. Set newEntry’s navigation id to global’s current navigation id.

3. Interaction Infrastructure

3.1. Interaction Context Intro

Soft navigation detection relies on the ability to track the causality of tasks and observe that certain operations (e.g., a DOM node append) were triggered by a specific user interaction.

This specification leverages the TC39 [ASYNC-CONTEXT] proposal to handle this propagation. Every new user interaction (as defined by Event Timing) or relevant navigation event creates a new InteractionContext. This context is stored in a hidden, internal-only AsyncContext.Variable (denoted as [[ActiveInteractionContext]]).

The web platform’s integration with AsyncContext ensures that this variable is automatically attached to asynchronous continuations (e.g., setTimeout, fetch, await), allowing the browser to attribute later effects back to the original interaction.

In addition to script propagation, this specification defines how user interactions that modify the DOM establish a set of modified nodes associated with the interaction, allowing subsequent rendering effects, like contentful paints, to be traced back to the initiating interaction context even when no asynchronous script is currently running.

3.2. The InteractionContext struct

InteractionContext is a struct used to maintain the data required to detect a soft navigation from a single interaction. It has the following items:

Note: Future versions of this specification might track all URL updates that occur during an interaction context to provide a more complete history of the navigation. The last URL value is tracked internally to ensure accurate attribution of effects back to the final state of the interaction, even if only the first URL value is currently exposed in the PerformanceSoftNavigation’s name.

3.3. Infrastructure Algorithms

To get the current interaction context given a Document document:
  1. Let context be the value of the internal AsyncContext.Variable [[ActiveInteractionContext]].

  2. If context is not null and context’s context document is not equal to document, return null.

  3. Return context.

To get or create the context for an interaction given a Document document and a PerformanceEventTiming timing entry:
  1. Let interaction id be timing entry’s interactionId.

  2. Assert interaction id is greater than 0.

  3. If document’s interaction id to interaction context[interaction id] exists, return document’s interaction id to interaction context[interaction id].

  4. Let interaction context be a new InteractionContext.

  5. Set interaction context’s id to interaction id.

  6. Set interaction context’s context document to document.

  7. Set interaction context’s start time to timing entry’s startTime.

  8. Set document’s interaction id to interaction context[interaction id] to interaction context.

  9. Return interaction context.

To update the interaction contexts for an event given a Document document and an Event event:
  1. Let timestamp be the current high resolution time given document’s relevant global object.

  2. Let is scroll be true if event’s type is "scroll", and false otherwise.

  3. Let is input be true if event’s type is an event type that would trigger has dispatched input event (as defined in [EVENT-TIMING]), and false otherwise.

  4. If is scroll is false and is input is false, return.

  5. For each interaction context of document’s interaction id to interaction context’s values:

    1. If is scroll is true and interaction context’s first scroll timestamp is 0:

      1. Set interaction context’s first scroll timestamp to timestamp.

    2. If is input is true and interaction context’s first input timestamp is 0:

      1. Set interaction context’s first input timestamp to timestamp.

To set the current interaction context for event dispatch given null or a PerformanceEventTiming object timing entry:
  1. If timing entry is null, return null.

  2. Let interaction id be timing entry’s interactionId.

  3. If interaction id is 0, return null.

  4. Let event be timing entry’s associated event.

  5. Let document be event’s relevant global object’s associated Document.

  6. Update the interaction contexts for an event given document and event.

  7. Let interaction context be the result of getting or createing the context for an interaction given document and timing entry.

  8. Set the value of the internal AsyncContext.Variable [[ActiveInteractionContext]] to interaction context.

  9. Return interaction context.

To unset the current interaction context after event dispatch:
  1. Set the value of the internal AsyncContext.Variable [[ActiveInteractionContext]] to null.

4. Interaction Contentful Paints

4.1. The InteractionContentfulPaint interface

[Exposed=Window]
interface InteractionContentfulPaint : PerformanceEntry {
    readonly attribute LargestContentfulPaint largestContentfulPaint;
    readonly attribute unsigned long long interactionId;

    object toJSON();
};

InteractionContentfulPaint includes PaintTimingMixin;

Each InteractionContentfulPaint has:

The largestContentfulPaint attribute’s getter must return this’s largest contentful paint.

The interactionId attribute’s getter must return this’s context’s id.

The name attribute’s getter must return the empty string.

The entryType attribute’s getter must return "interaction-contentful-paint".

The startTime attribute’s getter must return this’s context’s start time.

The duration attribute’s getter must return the difference between the default paint timestamp for this’s paint timing info and this’s context’s start time.

Note: While the entry dynamically queries static interaction properties (like interactionId and startTime) from its associated InteractionContext, it captures a static snapshot of the paint’s paint timing info and the candidate LargestContentfulPaint entry at creation time to ensure these metrics reflect the exact state of that visual update.

4.2. Interaction Contentful Paint Algorithms

To create an interaction contentful paint entry, given a Window window, an InteractionContext interaction context, a LargestContentfulPaint lcpEntry, and a paint timing info paintTimingInfo:
  1. Let entry be a new InteractionContentfulPaint object in window’s realm.

  2. Set entry’s context to interaction context.

  3. Set entry’s largest contentful paint to lcpEntry.

  4. Set entry’s associated paint timing info to paintTimingInfo.

  5. Return entry.

To process a new attributed contentful paint candidate given a largest contentful paint candidate lcpCandidate, a Document document, an InteractionContext interaction context, and a paint timing info paintTimingInfo:
  1. If interaction context’s first scroll timestamp is greater than 0 and lcpEntry’s renderTime is greater than interaction context’s first scroll timestamp, return.

  2. If interaction context’s first input timestamp is greater than 0 and lcpEntry’s renderTime is greater than interaction context’s first input timestamp, return.

  3. Let lcpEntry be the result of creating a LargestContentfulPaint entry with lcpCandidate, paintTimingInfo, and document.

  4. Let global be document’s relevant global object.

  5. Let paint timing info be lcpEntry’s associated paint timing info.

  6. Let icpEntry be the result of creating an interaction contentful paint entry given global, interaction context, lcpEntry, and paint timing info.

  7. Queue icpEntry.

  8. Add icpEntry to global’s performance entry buffer.

  9. If interaction context’s first contentful paint is null:

    1. Set interaction context’s first contentful paint to icpEntry.

  10. Set interaction context’s largest contentful paint to icpEntry.

  11. Set interaction context’s current largest contentful paint candidate to lcpCandidate.

Note: InteractionContentfulPaint entries are emitted to the performance timeline as they are detected, independently of whether the interaction eventually results in a soft navigation. This allows developers to monitor rendering updates for all interactions.

To report interaction contentful paints and soft navigations given a Document document, a paint timing info paintTimingInfo, an ordered set of pending image records paintedImages, and an ordered set of elements paintedTextNodes:
  1. Let contextToCandidateSets be a new map.

  2. For each record of paintedImages:

    1. Let element be record’s element.

    2. Let interaction context be the result of getting the paint attribution interaction context for element.

    3. If interaction context is not null:

      1. If contextToCandidateSets does not contain interaction context, then set contextToCandidateSets[interaction context] to « «», «» ».

      2. Append record to contextToCandidateSets[interaction context][0].

  3. For each element of paintedTextNodes:

    1. Let interaction context be the result of getting the paint attribution interaction context for element.

    2. If interaction context is not null:

      1. If contextToCandidateSets does not contain interaction context, then set contextToCandidateSets[interaction context] to « «», «» ».

      2. Append element to contextToCandidateSets[interaction context][1].

  4. For each interaction contextcandidateSets in contextToCandidateSets:

    1. Let newCandidate be the result of computing a new largest contentful paint candidate given document, candidateSets[0], candidateSets[1], and interaction context’s current largest contentful paint candidate.

    2. If newCandidate is not null:

      1. Process a new attributed contentful paint candidate given newCandidate, document, and interaction context, and paintTimingInfo.

      2. Evaluate soft navigation emission given document and interaction context.

4.3. Interaction Contentful Paint Attribution

An InteractionPaintTimingNodeState is a struct with the following items:


To determine if an InteractionPaintTimingNodeState node state is more recent than an InteractionPaintTimingNodeState or null other node state:
  1. Return true if other node state is null or node state’s modification id is greater than other node state’s modification id, and false otherwise.

To get the paint attribution interaction context for a given Node node:
  1. Let document be node’s node document.

  2. Let node state be document’s propagated node state[node] with default null.

  3. If node state is null return null, otherwise return node state’s context.

To record a node as modified for interaction paint timing given a Node target node:
  1. Let document be node’s node document.

  2. If target node is not exposed for paint timing given document, return.

  3. Let interaction context be the result of getting the current interaction context given document.

  4. If interaction context is null, return.

  5. If document’s last modification context is not equal to interaction context:

    1. Set document’s last modification context to interaction context.

    2. Increment document’s current modification generation id by 1.

  6. Let previous node state be document’s marked node state[target node] with default null.

  7. If previous node state is not null and previous node state’s modification id equals document’s current modification generation id, return.

  8. Let node state to a new InteractionPaintTimingNodeState.

  9. Set node state’s context to interaction context.

  10. Set node state’s modification id to document’s current modification generation id.

  11. Set document’s marked node state[node] to node state.

  12. Set document’s is interaction paint timing dirty to true.

To update the interaction context for a document and its descendants given a Document document:
  1. If document’s is interaction paint timing dirty is false, return.

  2. Update the interaction context for a node and its descendants given document and null.

  3. Set document’s is interaction paint timing dirty to false.

To update the interaction context for a node and its descendants given a Node node and an InteractionPaintTimingNodeState inherited node state or null:
  1. Let document be node’s node document.

  2. Let node state be document’s marked node state[node] with default null.

  3. If node state is not null:

    1. If node state is more recent than inherited node state:

      1. Set inherited node state to node state.

      2. If node is a Text node, then remove document’s marked node state[node].

    2. Otherwise, remove document’s marked node state[node].

  4. If inherited node state is not null and node is timing-eligible:

    1. Let attribution element be the result of getting the attribution element for node.

    2. Let previous propagated state be propagated node state[attribution element] with default null.

    3. If inherited node state is more recent than previous propagated state:

      1. Set propagated node state[attribution element] to inherited node state.

      2. If previous propagated state is null or previous propagated state’s context is not equal to inherited node state’s context, then reset paint tracking for attribution element.

  5. For each child child node of node, update the interaction context for a node and its descendants given child node and inherited node state.

Note: For simplicity, this algorithm walks the entire DOM whenever the propagated state needs to to be reprocessed. This can be optimized to only process parts of the DOM that are paintable, e.g. subtrees that are known to be non-visible or skipped by existing mechanisms like content-visibility or CSS containment could also be skipped during this process, as long as they are updated before the next time they are painted. Also note that this can be further optimized by merging these steps with another (pre-paint) tree walk, as long as the relevant state is updated before paint.

Note: The [CONTAINER-TIMING] API provides a mechanism for grouping rendering effects by their common DOM ancestor and report aggregated paint information to the performance timeline. In a future version of this specification, we plan to expand Container Timing to support multiple clients for a single container (i.e. the global "containertiming" attribute and per-interaction timing) to allow implementing interaction paint timing in terms of Container Timing. Each recorded node would be considered a container for the interaction that modified it, so that each interaction is associated with a set of containers. Then, this specification would track the largest contentful paint that occurs in a marked container, for each interaction. Furthermore, we could expose other useful information that Container Timing tracks, e.g. the aggregated total painted area of containers for each interaction.

5. Soft Navigations

5.1. The PerformanceSoftNavigation interface

[Exposed=Window]
interface PerformanceSoftNavigation : PerformanceEntry {
    readonly attribute NavigationType navigationType;
    readonly attribute unsigned long long interactionId;
    InteractionContentfulPaint? getLargestInteractionContentfulPaint();
};

PerformanceSoftNavigation includes PaintTimingMixin;

Each PerformanceSoftNavigation has:

The navigationType attribute’s getter must return this’s context’s navigation type.

The interactionId attribute’s getter must return this’s context’s id.

The getLargestInteractionContentfulPaint() method must return this’s context’s largest contentful paint.

The name attribute’s getter must return this’s context’s first URL value.

The entryType attribute’s getter must return "soft-navigation".

The startTime attribute’s getter must return this’s context’s start time.

The duration attribute’s getter must return the difference between this’s presentationTime and this’s context’s start time at the time of emission.

Note: In practice, getLargestInteractionContentfulPaint() is expected to return a non-null entry, as a confirmed soft navigation requires at least one detected interaction contentful paint to trigger its emission.

However, future iterations could evaluate whether a soft navigation could be considered committed immediately upon URL modification, prior to the first paint. In such a model, this method might return null at the time of emission.

The primary design consideration for this timing is the attribution of other timeline entries (e.g., LayoutShift, PerformanceResourceTiming, LongAnimationFrameTiming, etc) that occur in the interval between the URL modification and the first paint. Many sites commit the new URL immediately upon initiating a fetch request, for example, even while the current page remains in the previous navigation state. To ensure consistent timeline slicing, this specification attributes all such entries to the previous navigation identifier until the first paint confirms the transition.

5.2. Soft Navigation Algorithms

A soft navigation is a same-document navigation that satisfies the following conditions:

To evaluate soft navigation emission given a Document document and an InteractionContext interaction context:
  1. If interaction context’s emitted is true, return.

  2. If document’s active soft navigation candidate is not interaction context, return.

  3. If interaction context’s first URL value is null, return.

  4. If interaction context’s first contentful paint is null, return.

  5. Let window be document’s relevant global object.

  6. Let entry be the result of creating a soft navigation entry given window and interaction context.

  7. Emit a soft navigation entry given window and entry.

  8. Set interaction context’s emitted to true.

To create a soft navigation entry given a Window window, and an InteractionContext interaction context:
  1. Let entry be a new PerformanceSoftNavigation object in window’s realm.

  2. Set entry’s context to interaction context.

  3. Let first paint be interaction context’s first contentful paint.

  4. Assert first paint is not null.

  5. Set entry’s associated paint timing info to first paint’s associated paint timing info.

  6. Return entry.

To emit a soft navigation entry given a Window window and a PerformanceSoftNavigation entry:
  1. Increment the current navigation id given window.

  2. Queue entry.

  3. Add entry to window’s performance entry buffer.

Note: The navigationId for this PerformanceSoftNavigation entry is set automatically as part of queuing it to the performance timeline, matching the behavior of other PerformanceEntry types.

To process a same document commit given a Document document, string url, and NavigationType navigation type:
  1. If url is equal to document’s url, return.

  2. Let interaction context be the result of getting the current interaction context given document.

  3. If interaction context is null, return.

  4. Set interaction context’s last URL value to url.

  5. If interaction context’s first URL update timestamp is null:

    1. Set interaction context’s first URL update timestamp to the current high resolution time given document’s relevant global object.

    2. Set interaction context’s first URL value to url.

    3. Set interaction context’s navigation type to navigation type.

  6. Set document’s active soft navigation candidate to interaction context.

  7. Evaluate soft navigation emission given document and interaction context.

6. Specification Integrations

6.1. DOM integration

6.1.1. Document

Each document has an interaction id to interaction context, a map, initially empty.

Each document has an active soft navigation candidate, an InteractionContext or null, initially null.

Each document has a current modification generation id, a 64-bit unsigned integer initilized to 0.

Note: The current modification generation id changes when a relevant DOM modification occurs with a different InteractionContext from the previous modification. This allows grouping together related modifications, which enables comparing InteractionPaintTimingNodeState objects in terms of recency and optimizing which nodes need to be tracked.

Each document has a last modification context, an InteractionContext or null, initially null.

Each document has a marked node state, a map of Node to InteractionPaintTimingNodeState, initially empty.

Each document has a propagated node state, a map of Node to InteractionPaintTimingNodeState, initially empty.

Each document has an is interaction paint timing dirty, a boolean, initially false.

6.1.2. Node

At node insert, or when a node node is modified in one of the following ways:

Run the following steps:

  1. Record a node as modified for interaction paint timing given node.

6.2. HTML integration

6.2.1. History

In update document for history step application, before 5.5.1 (if documentsEntryChanged is true and if documentIsNew is false), process a same document commit given the Document, the target entry’s url, and "traverse".

In the shared history push/replace steps (as defined in [HTML]), after the URL is updated, process a same document commit given the Document, the new URL, and the operation type (either "push" or "replace").

6.2.2. Hard Navigation

When a new Window is created (e.g., during a "hard" navigation), its current navigation id is initialized as specified in § 2.1 Navigation ID.

In [NAVIGATION-TIMING], when creating the PerformanceNavigationTiming entry for the initial navigation, the user agent must set its navigationId to the Window’s current navigation id.

6.3. Event Timing integration

This specification extends the [EVENT-TIMING] definition of interactions to include additional event types that are relevant for modern web applications and Single Page Applications.

The following event types are considered to be part of an interaction (as defined in [EVENT-TIMING]):

When these events are dispatched as a result of a user interaction, the user agent must assign them a unique interactionId obtained by getting the next interactionId for the document’s relevant global object. If an event is triggered by a previous interaction that already has an assigned interactionId, the user agent should reuse that same identifier.

Note:These events are only reported as primary interactions when they are the initiating event from a user action (e.g., clicking the browser UI’s back button). In most other scenarios—such as a click handler manually manipulating history—the subsequent popstate or navigate events are not considered independent user interactions.

While these programmatically triggered events might not have the isTrusted flag set, they are correctly attributed back to the original interaction via [ASYNC-CONTEXT], as the history and navigation APIs are treated as asynchronous continuations of the initiating task.

Note: The events navigate, popstate, and hashchange are used as internal signals for tracking soft navigations and assigning interactionId. This specification does not require these event types to be exposed as PerformanceEventTiming entries to the performance timeline, leaving that determination to the [EVENT-TIMING] specification.

Note: The [EVENT-TIMING] specification is expected to be updated to explicitly define processingStart and processingEnd hooks, and to ensure interactionId assignment happens early enough for this integration. Today, interactionId assignment is typically deferred until the end of the event processing.

This specification uses unsigned long long for interactionId to ensure a safe global counter, while [EVENT-TIMING] currently defines it as unsigned long. This mismatch is expected to be resolved in future versions of both specifications.

To get the next interactionId for a Window window:
  1. Set window’s interaction count to window’s interaction count plus 1.

  2. Return window’s initial interactionId value plus (window’s interaction count times window’s interactionId increment).

In the modifications to the DOM specification’s event dispatch algorithm defined in [EVENT-TIMING]:
  1. Right after the step that sets timingEntry to the result of initialize and record event timing processing start, run the following step:

    1. Set the current interaction context for event dispatch given timingEntry.

  2. Right before the step that calls record event timing processing end, run the following step:

    1. Unset the current interaction context after event dispatch.

6.4. Paint Timing integration

This specification extends the [PAINT-TIMING] specification to reset paint tracking for elements that have been modified by interactions and to trigger paint attribution for rendered documents.

Change mark paint timing to add the following step after step 1, given a Document document:
  1. Update the interaction context for a document and its descendants given document.

Mark paint time mixes together steps that should come before and after the UA paints the document. The step added here is expected to occur before paint. [w3c/paint-timing Issue #126]

Change mark paint timing to add the following step after step 10.3 (report largest contentful paint), given a Document document, a paint timing info paintTimingInfo, an ordered set of pending image records paintedImages, and an ordered set of elements paintedTextNodes:
  1. Report interaction contentful paints and soft navigations given document, paintTimingInfo, paintedImages, and paintedTextNodes.

Add the following algorithm:

To reset paint tracking for a Node node:
  1. Reset the text element tracking node.

  2. Reset the image element tracking node.

This is a placeholder algorithm. We need to allow repaints for relevant elements, but the repaints should not affect Element Timing or LCP. Text and images have different mechanisms for detecting when a relevant paint has occurred, and both will need to be updated to support repaints.

Add the following algorithm:

To get the attribution element for a Node node:
  1. If node is a Text node, then return the Element that determines the containing block of node.

  2. Otherwise, return node.

6.5. Largest Contentful Paint (LCP) integration

7. Security & privacy considerations

Exposing Soft Navigations to the performance timeline doesn’t have security and privacy implications on its own. However, resetting the various paint timing entries as a result of a detected soft navigation can have implications, especially before visited links are partitioned. As such, exposing such paint operations without partitioning the :visited cache needs to only be done after careful analysis of the paint operations in question, to make sure they don’t expose the user’s history across origins.

8. Appendix: Overlapping Interactions and Race Conditions

This section is non-normative.

Web applications often process multiple user interactions in rapid succession. This specification handles such overlapping interactions through the following model:

Index

Terms defined by this specification

Terms defined by reference

References

Normative References

[CSS-DISPLAY-4]
Elika Etemad; Tab Atkins Jr.. CSS Display Module Level 4. URL: https://drafts.csswg.org/css-display-4/
[DOM]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[EVENT-TIMING]
Michal Mocny. Event Timing API. URL: https://w3c.github.io/event-timing/
[HR-TIME-3]
Yoav Weiss. High Resolution Time. URL: https://w3c.github.io/hr-time/
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[LARGEST-CONTENTFUL-PAINT]
Yoav Weiss. Largest Contentful Paint. URL: https://w3c.github.io/largest-contentful-paint/
[NAVIGATION-TIMING-2]
Yoav Weiss; Noam Rosenthal. Navigation Timing Level 2. URL: https://w3c.github.io/navigation-timing/
[PAINT-TIMING]
Ian Clelland; Noam Rosenthal. Paint Timing. URL: https://w3c.github.io/paint-timing/
[PERFORMANCE-TIMELINE]
Nicolas Pena Moreno. Performance Timeline. URL: https://w3c.github.io/performance-timeline/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/

Non-Normative References

[ASYNC-CONTEXT]
AsyncContext. URL: https://github.com/tc39/proposal-async-context
[CONTAINER-TIMING]
Container Timing API. URL: https://github.com/WICG/container-timing
[NAVIGATION-TIMING]
Zhiheng Wang. Navigation Timing. 17 December 2012. REC. URL: https://www.w3.org/TR/navigation-timing/

IDL Index

[Exposed=(Window,Worker)]
partial interface PerformanceEntry {
    readonly attribute unsigned long long navigationId;
};

[Exposed=Window]
interface InteractionContentfulPaint : PerformanceEntry {
    readonly attribute LargestContentfulPaint largestContentfulPaint;
    readonly attribute unsigned long long interactionId;

    object toJSON();
};

InteractionContentfulPaint includes PaintTimingMixin;

[Exposed=Window]
interface PerformanceSoftNavigation : PerformanceEntry {
    readonly attribute NavigationType navigationType;
    readonly attribute unsigned long long interactionId;
    InteractionContentfulPaint? getLargestInteractionContentfulPaint();
};

PerformanceSoftNavigation includes PaintTimingMixin;

Issues Index

This specification uses unsigned long long for interactionId to ensure a safe global counter, while [EVENT-TIMING] currently defines it as unsigned long. This mismatch is expected to be resolved in future versions of both specifications.
Mark paint time mixes together steps that should come before and after the UA paints the document. The step added here is expected to occur before paint. [w3c/paint-timing Issue #126]
This is a placeholder algorithm. We need to allow repaints for relevant elements, but the repaints should not affect Element Timing or LCP. Text and images have different mechanisms for detecting when a relevant paint has occurred, and both will need to be updated to support repaints.