From 7708a420b1735b90c9f82e77d803875bc0afca49 Mon Sep 17 00:00:00 2001 From: Domenic Denicola Date: Fri, 5 Feb 2021 14:36:58 -0500 Subject: [PATCH 1/2] Rename and update semantics for navigationStart(TimeStamp) Closes #8 by renaming. Closes #12 by changing the semantics to when the navigation is initiated. This might be refined further as we figure out navigation queuing. --- README.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index b63c4c4..1646e3a 100644 --- a/README.md +++ b/README.md @@ -550,12 +550,14 @@ This can be useful for cleaning up any information in secondary stores, such as The `window.appHistory` object has an event, `currententrychange`, which allows the application to react to any updates to the `appHistory.currentEntry` property. This includes both navigations that change its value, and calls to `appHistory.updateCurrentEntry()` that change its `state` or `url` properties. This cannot be intercepted or canceled, as it occurs after the navigation has already happened; it's just an after-the-fact notification. -This event has one special property, `event.navigationStartTimeStamp`, which for same-document navigations gives the value of `event.timeStamp` for the corresponding `navigate` event. This allows it to be used for determining the overall load time, including the time it took for a promise passed to `e.respondWith()` to settle: +This event has one special property, `event.navigationStart`, 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, `navigationStart` will be `null`. + +"Initiated" means either when the corresponding API was called (like `location.href` or `appHistory.pushNewEntry()`), or when the user activated the corresponding `` element, or submitted the corresponding `
`. This allows it to be used for determining the overall time from navigation initiation to navigation completion, including the time it took for a promise passed to `e.respondWith()` to settle: ```js appHistory.addEventListener("currententrychange", e => { - if (e.navigationStartTimeStamp) { - const loadTime = e.timeStamp - e.navigationStartTimeStamp; + if (e.navigationStart) { + const loadTime = e.timeStamp - e.navigationStart; document.querySelector("#status-bar").textContent = `Loaded in ${loadTime} ms!`; analyticsPackage.sendEvent("single-page-app-nav", { loadTime }); @@ -565,7 +567,7 @@ appHistory.addEventListener("currententrychange", e => { }); ``` -_TODO: could we populate this for cross-document navigations too? Then it kind of overlaps with existing timing APIs, and is probably a lot harder to implement..._ +_TODO: reconsider cross-document navigations. There will only be one (the initial load of the page); should we even fire this event in that case? Could we give `navigationStart` a useful value there, if we do?_ _TODO: Add a non-analytics examples, similar to how people use `popstate` today._ @@ -802,6 +804,7 @@ This proposal is based on [an earlier revision](https://github.com/slightlyoff/h Thanks also to [@chrishtr](https://github.com/chrishtr), [@dvoytenko](https://github.com/dvoytenko), +[@esprehn](https://github.com/esprehn), [@housseindjirdeh](https://github.com/housseindjirdeh), [@jakearchibald](https://github.com/jakearchibald), and [@slightlyoff](https://github.com/slightlyoff) @@ -895,10 +898,10 @@ dictionary AppHistoryUpcomingNavigateEventInit : EventInit { interface AppHistoryCurrentEntryChangeEvent : Event { constructor(DOMString type, optional AppHistoryCurrentEntryChangeEventInit eventInit = {}); - readonly attribute DOMHighResTimeStamp? navigationStartTimeStamp; + readonly attribute DOMHighResTimeStamp? navigationStart; }; dictionary AppHistoryCurrentEntryChangeEventInit : EventInit { - DOMHighResTimeStamp? navigationStartTimeStamp = null; + DOMHighResTimeStamp? navigationStart = null; }; ``` From 7b51341489ddb79a00a3b172b47051992ee16019 Mon Sep 17 00:00:00 2001 From: Domenic Denicola Date: Thu, 11 Feb 2021 15:21:00 -0500 Subject: [PATCH 2/2] startTime; point to 33 --- README.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 1646e3a..1b56ca4 100644 --- a/README.md +++ b/README.md @@ -550,14 +550,14 @@ This can be useful for cleaning up any information in secondary stores, such as The `window.appHistory` object has an event, `currententrychange`, which allows the application to react to any updates to the `appHistory.currentEntry` property. This includes both navigations that change its value, and calls to `appHistory.updateCurrentEntry()` that change its `state` or `url` properties. This cannot be intercepted or canceled, as it occurs after the navigation has already happened; it's just an after-the-fact notification. -This event has one special property, `event.navigationStart`, 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, `navigationStart` will be `null`. +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`. "Initiated" means either when the corresponding API was called (like `location.href` or `appHistory.pushNewEntry()`), or when the user activated the corresponding `` element, or submitted the corresponding ``. This allows it to be used for determining the overall time from navigation initiation to navigation completion, including the time it took for a promise passed to `e.respondWith()` to settle: ```js appHistory.addEventListener("currententrychange", e => { - if (e.navigationStart) { - const loadTime = e.timeStamp - e.navigationStart; + if (e.startTime) { + const loadTime = e.timeStamp - e.startTime; document.querySelector("#status-bar").textContent = `Loaded in ${loadTime} ms!`; analyticsPackage.sendEvent("single-page-app-nav", { loadTime }); @@ -567,7 +567,9 @@ appHistory.addEventListener("currententrychange", e => { }); ``` -_TODO: reconsider cross-document navigations. There will only be one (the initial load of the page); should we even fire this event in that case? Could we give `navigationStart` a useful value there, if we do?_ +_TODO: reconsider cross-document navigations. There will only be one (the initial load of the page); should we even fire this event in that case? (That's [#31](https://github.com/WICG/app-history/issues/31).) Could we give `startTime` a useful value there, if we do?_ + +_TODO: is this property-on-the-event design the right one, or should we integrate with the performance timeline APIs, or...? Discuss in [#33](https://github.com/WICG/app-history/issues/33)._ _TODO: Add a non-analytics examples, similar to how people use `popstate` today._ @@ -898,10 +900,10 @@ dictionary AppHistoryUpcomingNavigateEventInit : EventInit { interface AppHistoryCurrentEntryChangeEvent : Event { constructor(DOMString type, optional AppHistoryCurrentEntryChangeEventInit eventInit = {}); - readonly attribute DOMHighResTimeStamp? navigationStart; + readonly attribute DOMHighResTimeStamp? startTime; }; dictionary AppHistoryCurrentEntryChangeEventInit : EventInit { - DOMHighResTimeStamp? navigationStart = null; + DOMHighResTimeStamp? startTime = null; }; ```