The PerformanceSoftNavigation interface provides timing information about soft navigations as used by client-side routing on single-page application (SPA) sites. It is emitted when a browser observes a soft navigation to have taken place.
This interface directly defines the following properties:
The id of the interaction that resulted in the soft navigation.
The id of the navigation, unique to this page load.
The type of the navigation.
Returns the timestamp of when the first rendering phase ended and the paint phase started.
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 "soft-navigation".
PerformanceEntry.duration Read only Returns the result of PerformanceSoftNavigation.presentationTime - PerformanceEntry.startTime.
PerformanceEntry.name Read only The new URL navigated to.
PerformanceEntry.startTime Read only Returns the timestamp of the interaction that resulted in the soft navigation.
This interface also inherits methods from PerformanceEntry.
Returns the current largest InteractionContentfulPaint for this soft navigation.
The PerformanceSoftNavigation interface is driven by the browser observing the following:
Having the browser provide this rather than a routing framework calling an API to emit this entry allows SPA performance timing to be measured consistently regardless of how different applications handle navigations (for example, updating the URL at the start or the end of navigation processing).
The PerformanceSoftNavigation interface allows developers to measure SPA performance metrics such as:
InteractionContentfulPaint for the soft navigation.In the following example, a PerformanceObserver is used to log 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("Soft Nav:", entry.startTime, entry.name);
}
});
observer.observe({ type: "soft-navigation", buffered: true });