diff --git a/README.md b/README.md
index 7117e8c..f2eaae9 100644
--- a/README.md
+++ b/README.md
@@ -48,14 +48,12 @@ backButtonEl.addEventListener("click", () => {
});
```
-The new `currentchange` event fires whenever the current history entry changes, and includes the time it took for a single-page application nav to settle:
+A new extension to the [performance timeline API](https://developer.mozilla.org/en-US/docs/Web/API/Performance_Timeline) allows you to calculate the duration of single-page navigations, including any asynchronous work performed by the `navigate` handler:
```js
-appHistory.addEventListener("currentchange", e => {
- if (e.startTime) {
- analyticsPackage.sendEvent("single-page-app-nav", { loadTime: e.timeStamp - e.startTime });
- }
-});
+for (const entry of performance.getEntriesByType("same-document-navigation")) {
+ console.log(`It took ${entry.duration} ms to navigate to the URL ${entry.name}`);
+}
```
@@ -86,6 +84,7 @@ appHistory.addEventListener("currentchange", e => {
- [Example: next/previous buttons](#example-nextprevious-buttons)
- [Per-entry events](#per-entry-events)
- [Current entry change monitoring](#current-entry-change-monitoring)
+ - [Performance timeline API integration](#performance-timeline-api-integration)
- [Complete event sequence](#complete-event-sequence)
- [Guide for migrating from the existing history API](#guide-for-migrating-from-the-existing-history-api)
- [Performing navigations](#performing-navigations)
@@ -225,15 +224,6 @@ The current entry can be replaced with a new entry, with a new `AppHistoryEntry`
- When using the `navigate` event to [convert a cross-document replace navigation into a same-document navigation](#navigation-monitoring-and-interception).
-In both cases, for same-document navigations a `currentchange` event will fire on `appHistory`:
-
-```js
-appHistory.addEventListener("currentchange", () => {
- // appHistory.current has changed: either to a completely new entry (with new key),
- // or it has been replaced (keeping the same key).
-});
-```
-
### Inspection of the app history list
In addition to the current entry, the entire list of app history entries can be inspected, using `appHistory.entries()`, which returns an array of `AppHistoryEntry` instances. (Recall that all app history entries are same-origin contiguous entries for the current frame, so this is not a security issue.)
@@ -500,7 +490,7 @@ This does not yet solve all accessibility problems with single-page navigations.
Continuing with the theme of `respondWith()` giving ecosystem benefits beyond just web developer convenience, telling the browser about the start time, duration, end time, and success/failure if a single-page app navigation has benefits for metrics gathering.
-In particular, analytics frameworks would be able to consume this information from the browser in a way that works across all applications using the app history API. See the example in the [Current entry change monitoring](#current-entry-change-monitoring) section for one way this could look; other possibilities include integrating into the existing [performance APIs](https://w3c.github.io/performance-timeline/).
+In particular, analytics frameworks would be able to consume this information from the browser in a way that works across all applications using the app history API. See the discussion on [performance timeline API integration](#performance-timeline-api-integration) for what we are proposing there.
This standardized notion of single-page navigations also gives a hook for other useful metrics to build off of. For example, you could imagine variants of the `"first-paint"` and `"first-contentful-paint"` APIs which are collected after the `navigate` event is fired. Or, you could imagine vendor-specific or application-specific measurements like [Cumulative Layout Shift](https://web.dev/cls/) or React hydration time being reset after such navigations begin.
@@ -875,34 +865,34 @@ await appHistory.navigate("/1-b");
This can be useful for cleaning up any information in secondary stores, such as `sessionStorage` or caches, when we're guaranteed to never reach those particular history entries again.
-### Current entry change monitoring
+### Performance timeline API integration
-**Although the basic idea of an event for when `appHistory.current` changes will probably survive, much of this section needs revamping. See the several discussions linked below.**
+The [performance timeline API](https://w3c.github.io/performance-timeline/) provides a generic framework for the browser to signal about interesting events, their durations, and their associated data via `PerformanceEntry` objects. For example, cross-document navigations are done with the [navigation timing API](https://w3c.github.io/navigation-timing/), which uses a subclass of `PerformanceEntry` called `PerformanceNavigationTiming`.
-The `window.appHistory` object has an event, `currentchange`, which allows the application to react to any updates to the `appHistory.current` property. This includes both navigations that change its value, and calls to `appHistory.navigate()` that change its state or URL. This cannot be intercepted or canceled, as it occurs after the navigation has already happened; it's just an after-the-fact notification.
+Until now, it has not been possible to measure such data for same-document navigations. This is somewhat understandable, as such navigations have always been "zero duration": they occur instantaneously when the application calls `history.pushState()` or `history.replaceState()`. So measuring them isn't that interesting. But with the app history API, [browsers know about the start time, end time, and duration of the navigation](#measuring-standardized-single-page-navigations), so we can give useful performance entries.
-This event has one special property, `event.startTime`, which for [same-document](#appendix-types-of-navigations) navigations gives the value of `performance.now()` when the navigation was initiated. This includes for navigations that were originally [cross-document](#appendix-types-of-navigations), like the user clicking on ``, but were transformed into same-document navigations by [navigation interception](#navigation-monitoring-and-interception). For completely cross-document navigations, `startTime` will be `null`.
+The `PerformanceEntry` instances for such same-document navigations are instances of a new subclass, `SameDocumentNavigationEntry`, with the following properties:
-"Initiated" means either when the corresponding API was called (like `location.href` or `appHistory.navigate()`), or when the user activated the corresponding `` element, or submitted the corresponding `