From db40939cf9e08c52aced998b9acb4453aac5dbca Mon Sep 17 00:00:00 2001 From: Ian Clelland Date: Wed, 15 Sep 2021 11:30:17 -0400 Subject: [PATCH 1/8] Add navigationId to PerformanceEntry --- index.html | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/index.html b/index.html index e6f9e11..97f0bc1 100644 --- a/index.html +++ b/index.html @@ -70,6 +70,9 @@
  • Exposes {{PerformanceEntry}} in Web Workers [[WORKERS]];
  • +
  • Formalizes support for multiple navigation events over a document's + lifetime. +
  • Adds support for {{PerformanceObserver}}.
  • @@ -246,6 +249,7 @@

    Performance Timeline

  • An integer dropped entries count that is initially 0.
  • +
  • An integer current navigation id that is initially 0.
  • In order to get the relevant performance entry tuple, given entryType and globalObject as input, run the @@ -258,6 +262,17 @@

    Performance Timeline

    map, given entryType as the key. +

    The session + history document visibility change steps defined by this specification are:

    +
      +
    1. Increment newDocument's [=relevant global object=]'s current navigation + id.
    2. +
    +

    These steps will be called from [[HTML]]'s traverse the history + algorithm whenever a document is restored from the bfcache, immediately before the + [=Window/pageshow=] event is fired.

    Extensions to the {{Performance}} interface

    This extends the {{Performance}} interface from [[HR-TIME-3]] and @@ -308,6 +323,7 @@

    The PerformanceEntry interface

    readonly attribute DOMString entryType; readonly attribute DOMHighResTimeStamp startTime; readonly attribute DOMHighResTimeStamp duration; + readonly attribute unsigned long navigationId; [Default] object toJSON(); };
    @@ -344,6 +360,12 @@

    The PerformanceEntry interface

    duration concept doesn't apply, a performance metric may choose to return a `duration` of 0. +
    navigationId
    +
    + This attribute MUST return the value of the global object's current + navigation id at the time that this PerformanceEntry was + queued. +

    When toJSON is called, run [[WebIDL]]'s default toJSON steps.

    @@ -672,6 +694,8 @@

    Queue a PerformanceEntry

  • Let relevantGlobal be newEntry's relevant global object.
  • +
  • Set newEntry's navigationId + to relevantGlobal's current navigation id.
  • For each registered performance observer regObs in relevantGlobal's list of registered performance observer objects:
      From 324898517aec91c2dc1e47d68591b7034bea9982 Mon Sep 17 00:00:00 2001 From: Ian Clelland Date: Fri, 1 Oct 2021 14:49:23 -0400 Subject: [PATCH 2/8] Move navigation counter to HTML --- index.html | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/index.html b/index.html index 97f0bc1..412193b 100644 --- a/index.html +++ b/index.html @@ -249,7 +249,6 @@

      Performance Timeline

    1. An integer dropped entries count that is initially 0.
    2. -
    3. An integer current navigation id that is initially 0.
    4. In order to get the relevant performance entry tuple, given entryType and globalObject as input, run the @@ -262,17 +261,6 @@

      Performance Timeline

      map, given entryType as the key.
    -

    The session - history document visibility change steps defined by this specification are:

    -
      -
    1. Increment newDocument's [=relevant global object=]'s current navigation - id.
    2. -
    -

    These steps will be called from [[HTML]]'s traverse the history - algorithm whenever a document is restored from the bfcache, immediately before the - [=Window/pageshow=] event is fired.

    Extensions to the {{Performance}} interface

    This extends the {{Performance}} interface from [[HR-TIME-3]] and @@ -362,9 +350,7 @@

    The PerformanceEntry interface

    navigationId
    - This attribute MUST return the value of the global object's current - navigation id at the time that this PerformanceEntry was - queued. + This attribute MUST return the value of this's navigationId.

    When toJSON is called, run [[WebIDL]]'s default toJSON @@ -694,8 +680,17 @@

    Queue a PerformanceEntry

  • Let relevantGlobal be newEntry's relevant global object.
  • -
  • Set newEntry's navigationId - to relevantGlobal's current navigation id.
  • +
  • If relevantGlobal's environment settings object has a + [=environment settings object/responsible document=]: +
      +
    1. Set newEntry's navigationId to the value of + relevantGlobal's environment settings object's [=environment + settings object/responsible document=]'s navigation counter.
    2. +
    +
  • +
  • Otherwise, set newEntry's navigationId to 0.
  • For each registered performance observer regObs in relevantGlobal's list of registered performance observer objects:
      From 6e5497ef79cfc1f64125aec2d8fc2cc46a92075e Mon Sep 17 00:00:00 2001 From: Ian Clelland Date: Fri, 26 Nov 2021 12:35:02 -0500 Subject: [PATCH 3/8] Add proposed update to explainer text --- explainer.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/explainer.md b/explainer.md index 7c6d672..47401dd 100644 --- a/explainer.md +++ b/explainer.md @@ -59,6 +59,8 @@ The entry has the following attributes: * `entryType`: a string representing the type of performance data being exposed. It is also used to filter entries in the `getEntriesByType()` method and in the `PerformanceObserver`. * `startTime`: a timestamp representing the starting point for the performance data being recorded. The semantics of this attribute depend on the `entryType`. * `duration`: a time duration representing the duration of the performance data being recorded. The semantics of this one also depend on the `entryType`. +* `navigationId`: an integer indicating how many times the user has navigated to this document +since it was initially loaded. If these sound abstract, it’s because they are. A specification whose goal is to expose new measurements to web developers will define a new interface which extends `PerformanceEntry`. @@ -150,6 +152,21 @@ For entryTypes with a fixed amount of entries, like Paint Timing, using the poll At the same time, the callback is more useful for cases where there is varying amount of entries of the given entryType, like in Resource Timing. The web performance monitoring service can process all the performance information while the page is still running and only has to do very minimal work when the data needs to be reported. +## Page lifetime issues +When this API was originally designed, documents had a relatively simple lifecycle: they were +loaded when the user navigated to them, and unloaded when the user navigated away, with the +JavaScript environment being torn down at that time. Since then, the sitution has become more +complex, with many browsers introducing a back-forwards-cache, with which a user can return +a document wich they have previously navigated away from. The web has also seen a rise in +popularity of Single Page Apps, where what appears to the user to be a navigation is actually +just a change in state of a running page. In both of these situations, a navigation (or what +appears to the user as a navigation) can occur without the performance timeline being reset. +In order to allow developers to reason about such events during the life of a page, +PerformanceEntry objects now include a navigation counter field. This field captures the +count of navigations which had occurred when the entry was generated (starting at 1 when the +document is initially loaded, and being incremented by one with each subsequent navigation of +the document.) + # Standards Status The Performance Timeline specification is widely approved. There are differences in what kinds of performance data is exposed on different user agents, but this specification does not concern itself with that, and that is delegated to the new specifications that describe new data. From 564c3cb88adb65c527b451225f91642e6fc28809 Mon Sep 17 00:00:00 2001 From: Ian Clelland Date: Sun, 18 Sep 2022 20:23:27 -0700 Subject: [PATCH 4/8] Add HTML concepts into this doc until they are merged there. --- index.html | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index 86e843d..56f60ca 100644 --- a/index.html +++ b/index.html @@ -678,13 +678,11 @@

      Queue a PerformanceEntry

    1. Let relevantGlobal be newEntry's relevant global object.
    2. -
    3. If relevantGlobal's environment settings object has a - [=environment settings object/responsible document=]: +
    4. If relevantGlobal has an [=associated document=]:
      1. Set newEntry's navigationId to the value of - relevantGlobal's environment settings object's [=environment - settings object/responsible document=]'s navigation counter.
      2. + relevantGlobal's [=associated document=]'s [=navigation id=].
    5. Otherwise, set newEntry's Determine if a performance entry buffer is full
  • +
    +

    Integration with HTML

    +

    This section defines concepts which should rightly be defined in + [[HTML]]. Remove this section once those definitions exist there.

    +

    A [=Document=] has a navigation id which is an integer. It is + initially 0.

    +

    In [[HTML#history-traversal]], in the [[HTML#traverse-the-history]] + algorithm, add the following line after step 4.7.2: +

      +
    1. Increment newDocument's [=navigation id=].
    2. +
    +

    +

    Privacy Considerations

    This specification extends the {{Performance}} interface defined by [[HR-TIME-3]] and From 1497e2a35b4f89ba541fc6889b186c410bbaf1dd Mon Sep 17 00:00:00 2001 From: Ian Clelland Date: Mon, 24 Apr 2023 15:00:53 -0400 Subject: [PATCH 5/8] Change navigationId to a string, and add algorithm to queue navigation performance entries --- explainer.md | 12 +++---- index.html | 90 +++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 70 insertions(+), 32 deletions(-) diff --git a/explainer.md b/explainer.md index 47401dd..43581c6 100644 --- a/explainer.md +++ b/explainer.md @@ -59,8 +59,7 @@ The entry has the following attributes: * `entryType`: a string representing the type of performance data being exposed. It is also used to filter entries in the `getEntriesByType()` method and in the `PerformanceObserver`. * `startTime`: a timestamp representing the starting point for the performance data being recorded. The semantics of this attribute depend on the `entryType`. * `duration`: a time duration representing the duration of the performance data being recorded. The semantics of this one also depend on the `entryType`. -* `navigationId`: an integer indicating how many times the user has navigated to this document -since it was initially loaded. +* `navigationId`: a string identifying the `PerformanceEntry` object corresponding to the last navigation or navigation-like event that had occurred in the document at the time that this `PerformanceEntry` object was recorded. If these sound abstract, it’s because they are. A specification whose goal is to expose new measurements to web developers will define a new interface which extends `PerformanceEntry`. @@ -161,11 +160,10 @@ a document wich they have previously navigated away from. The web has also seen popularity of Single Page Apps, where what appears to the user to be a navigation is actually just a change in state of a running page. In both of these situations, a navigation (or what appears to the user as a navigation) can occur without the performance timeline being reset. -In order to allow developers to reason about such events during the life of a page, -PerformanceEntry objects now include a navigation counter field. This field captures the -count of navigations which had occurred when the entry was generated (starting at 1 when the -document is initially loaded, and being incremented by one with each subsequent navigation of -the document.) +In order to allow developers to reason about such events during the life of a page, some +PerformanceEntry objects mark navigations, or navigation-like events. All PerformanceEntry +objects include a navigation ID field, which links each PerformanceEntry to the most recent +navigation entry which had occurred when the entry was generated. # Standards Status The Performance Timeline specification is widely approved. diff --git a/index.html b/index.html index 17b1c25..6218f39 100644 --- a/index.html +++ b/index.html @@ -247,6 +247,12 @@

    Performance Timeline

    +

    Each Document has:

    +

    In order to get the relevant performance entry tuple, given entryType and globalObject as input, run the following steps:

    @@ -308,7 +314,7 @@

    The PerformanceEntry interface

    readonly attribute DOMString entryType; readonly attribute DOMHighResTimeStamp startTime; readonly attribute DOMHighResTimeStamp duration; - readonly attribute unsigned long navigationId; + readonly attribute DOMString navigationId; [Default] object toJSON(); };
    @@ -592,6 +598,7 @@

    PerformanceObserverEntryList interface

    PerformanceEntryList getEntries(); PerformanceEntryList getEntriesByType (DOMString type); PerformanceEntryList getEntriesByName (DOMString name, optional DOMString type); + PerformanceEntryList getEntriesByNavigationId (DOMString navigationId); };

    Each {{PerformanceObserverEntryList}} object has an associated @@ -600,24 +607,34 @@

    PerformanceObserverEntryList interface

    getEntries() method

    Returns a PerformanceEntryList object returned by filter - buffer by name and type algorithm with this's entry list, - name and type set to null.

    + buffer algorithm with this's entry list, + name, type and navigationId set to + null.

    getEntriesByType() method

    Returns a PerformanceEntryList object returned by filter - buffer by name and type algorithm with this's entry list, - name set to null, and type set to the - method's input type parameter.

    + buffer algorithm with this's entry list, + name set to null, type set to the + method's input type parameter, and navigationId + set to null.

    getEntriesByName() method

    Returns a PerformanceEntryList object returned by filter - buffer by name and type algorithm with this's entry list, + buffer algorithm with this's entry list, name set to the method input name parameter, and type set to null if optional `entryType` is omitted, or set to the method's input type parameter otherwise.

    +
    +

    getEntriesByNavigationId() method

    +

    Returns a PerformanceEntryList object returned by filter + buffer algorithm with this's entry list, + name and type set to null, and + navigationId set to the method's input + navigationId parameter.

    +
    @@ -681,11 +698,11 @@

    Queue a PerformanceEntry

    1. Set newEntry's navigationId to the value of - relevantGlobal's [=associated document=]'s [=navigation id=].
    2. + relevantGlobal's [=associated document=]'s [=most recent navigation=]'s {{PerformanceEntry/navigationId}}.
  • Otherwise, set newEntry's navigationId to 0.
  • + data-lt="PerformanceEntry.navigationId">navigationId to null.
  • For each registered performance observer regObs in relevantGlobal's list of registered performance observer objects:
      @@ -731,6 +748,24 @@

      Queue a PerformanceEntry

  • +
    +

    Queue a navigation PerformanceEntry

    +

    To queue a navigation PerformanceEntry (newEntry), run + these steps:

    +
      +
    1. Let navigationId be the result of running generate a navigationId for newEntry.
    2. +
    3. Let relevantGlobal be newEntry's relevant + global object. +
    4. +
    5. Set newEntry's {{PerformanceEntry/navigationId}} to navigationId.
    6. +
    7. If relevantGlobal has an [=associated document=]: +
        +
      1. Set relevantGlobal's [=associated document=]'s [=most recent navigation=] to newEntry.
      2. +
      +
    8. +
    9. Queue a PerformanceEntry with newEntry as input.
    10. +
    +

    Queue the PerformanceObserver task

    When asked to queue the PerformanceObserver task, given @@ -843,7 +878,7 @@

    Filter buffer map by name and type

    continue to the next tuple.
  • Let entries be the result of running filter - buffer by name and type with buffer, name + buffer with buffer, name and type as inputs.
  • For each entry in entries, @@ -857,10 +892,10 @@

    Filter buffer map by name and type

  • -

    Filter buffer by name and type

    -

    When asked to run the filter buffer by name and type - algorithm, with buffer, name, and type - as inputs, run the following steps:

    +

    Filter buffer

    +

    When asked to run the filter buffer + algorithm, with buffer, name, type, and + navigationId as inputs, run the following steps:

    1. Let result be an initially empty list.
    2. @@ -875,6 +910,12 @@

      Filter buffer by name and type

      identical to entry's name attribute, continue to next entry. +
    3. If navigationId is not null and if + navigationId is not + identical to entry's + navigationId attribute, continue to next + entry. +
    4. [=list/append=] entry to result.
    @@ -900,19 +941,18 @@

    Determine if a performance entry buffer is full

  • Return true.
  • - -
    -

    Integration with HTML

    -

    This section defines concepts which should rightly be defined in - [[HTML]]. Remove this section once those definitions exist there.

    -

    A [=Document=] has a navigation id which is an integer. It is - initially 0.

    -

    In [[HTML#history-traversal]], in the [[HTML#traverse-the-history]] - algorithm, add the following line after step 4.7.2: +

    +

    Generate a navigationId

    +

    When asked to generate a navigationId for a + PerformanceEntry entry, run the following steps:

      -
    1. Increment newDocument's [=navigation id=].
    2. +
    3. Let type be entry's entryType.
    4. +
    5. Let startTime be entry's startTime. +
    6. +
    7. Return the [=string/concatenation=] of « type, + time » using U+002D HYPHEN-MINUS.
    -

    +

    Privacy Considerations

    From 8e34f8f8a3c60c8d38d1cd11eeeea73ca06a3544 Mon Sep 17 00:00:00 2001 From: Ian Clelland Date: Wed, 4 Oct 2023 14:16:56 -0400 Subject: [PATCH 6/8] Addressing review comments * Fix typos * Remove getEntriesByNavigationId() * Convert timestamps to strings for concatenation --- explainer.md | 8 ++++---- index.html | 57 ++++++++++++++++++++++++---------------------------- 2 files changed, 30 insertions(+), 35 deletions(-) diff --git a/explainer.md b/explainer.md index 43581c6..3b90b94 100644 --- a/explainer.md +++ b/explainer.md @@ -155,15 +155,15 @@ The web performance monitoring service can process all the performance informati When this API was originally designed, documents had a relatively simple lifecycle: they were loaded when the user navigated to them, and unloaded when the user navigated away, with the JavaScript environment being torn down at that time. Since then, the sitution has become more -complex, with many browsers introducing a back-forwards-cache, with which a user can return -a document wich they have previously navigated away from. The web has also seen a rise in +complex, with many browsers introducing a back-forward cache, with which a user can return to +a document which they have previously navigated away from. The web has also seen a rise in popularity of Single Page Apps, where what appears to the user to be a navigation is actually just a change in state of a running page. In both of these situations, a navigation (or what appears to the user as a navigation) can occur without the performance timeline being reset. In order to allow developers to reason about such events during the life of a page, some PerformanceEntry objects mark navigations, or navigation-like events. All PerformanceEntry -objects include a navigation ID field, which links each PerformanceEntry to the most recent -navigation entry which had occurred when the entry was generated. +objects include a navigation ID field, which ties each PerformanceEntry to the most recent +navigation entry which had occurred before the entry was generated. # Standards Status The Performance Timeline specification is widely approved. diff --git a/index.html b/index.html index 6218f39..8eb4051 100644 --- a/index.html +++ b/index.html @@ -47,7 +47,7 @@ "check-punctuation": true, }, doJsonLd: true, - xref: ["hr-time-3", "infra", "html", "dom"], + xref: ["hr-time-3", "infra", "html", "dom", 'ecmascript'], mdn: "performance-timeline", }; @@ -249,7 +249,7 @@

    Performance Timeline

    Each Document has:

    @@ -598,7 +598,6 @@

    PerformanceObserverEntryList interface

    PerformanceEntryList getEntries(); PerformanceEntryList getEntriesByType (DOMString type); PerformanceEntryList getEntriesByName (DOMString name, optional DOMString type); - PerformanceEntryList getEntriesByNavigationId (DOMString navigationId); };

    Each {{PerformanceObserverEntryList}} object has an associated @@ -607,34 +606,24 @@

    PerformanceObserverEntryList interface

    getEntries() method

    Returns a PerformanceEntryList object returned by filter - buffer algorithm with this's entry list, - name, type and navigationId set to - null.

    + buffer by name and type algorithm with this's entry list, + name and type set to null.

    getEntriesByType() method

    Returns a PerformanceEntryList object returned by filter - buffer algorithm with this's entry list, - name set to null, type set to the - method's input type parameter, and navigationId - set to null.

    + buffer by name and type algorithm with this's entry list, + name set to null, and type set to the + method's input type parameter.

    getEntriesByName() method

    Returns a PerformanceEntryList object returned by filter - buffer algorithm with this's entry list, + buffer by name and type algorithm with this's entry list, name set to the method input name parameter, and type set to null if optional `entryType` is omitted, or set to the method's input type parameter otherwise.

    -
    -

    getEntriesByNavigationId() method

    -

    Returns a PerformanceEntryList object returned by filter - buffer algorithm with this's entry list, - name and type set to null, and - navigationId set to the method's input - navigationId parameter.

    -
    @@ -878,7 +867,7 @@

    Filter buffer map by name and type

    continue to the next tuple.
  • Let entries be the result of running filter - buffer with buffer, name + buffer by name and type with buffer, name and type as inputs.
  • For each entry in entries, @@ -892,10 +881,10 @@

    Filter buffer map by name and type

  • -

    Filter buffer

    -

    When asked to run the filter buffer - algorithm, with buffer, name, type, and - navigationId as inputs, run the following steps:

    +

    Filter buffer by name and type

    +

    When asked to run the filter buffer by name and type + algorithm, with buffer, name, and type + as inputs, run the following steps:

    1. Let result be an initially empty list.
    2. @@ -910,12 +899,6 @@

      Filter buffer

      identical to entry's name attribute, continue to next entry. -
    3. If navigationId is not null and if - navigationId is not - identical to entry's - navigationId attribute, continue to next - entry. -
    4. [=list/append=] entry to result.
    @@ -948,9 +931,21 @@

    Generate a navigationId

    1. Let type be entry's entryType.
    2. Let startTime be entry's startTime. +
    3. Let timeString be the result of calling + {{Number/toString(radix)}}(startTime, 10). +
    4. +
    5. If timeString contains the code point U+002E FULL STOP: +
        +
      1. Assert: timeString contains only one instance + of U+002E FULL STOP.
      2. +
      3. Assert: timeString contains at least one code + point following the U+002E FULL STOP code point.
      4. +
      5. Truncate timeString after the first code point + following the U+002E FULL STOP code point.
      6. +
    6. Return the [=string/concatenation=] of « type, - time » using U+002D HYPHEN-MINUS.
    7. + timeString » using U+002D HYPHEN-MINUS.
    From 771922d7acf0e183ef4af5d0b8e10d6db5012d55 Mon Sep 17 00:00:00 2001 From: Ian Clelland Date: Fri, 6 Oct 2023 14:52:10 -0400 Subject: [PATCH 7/8] Introduce an id, and change navigationId to point to it. --- index.html | 70 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 24 deletions(-) diff --git a/index.html b/index.html index 8eb4051..58bd63e 100644 --- a/index.html +++ b/index.html @@ -47,7 +47,7 @@ "check-punctuation": true, }, doJsonLd: true, - xref: ["hr-time-3", "infra", "html", "dom", 'ecmascript'], + xref: ["hr-time-3", "infra", "html", "dom"], mdn: "performance-timeline", }; @@ -246,6 +246,9 @@

    Performance Timeline

  • An integer dropped entries count that is initially 0.
  • +
  • An integer last performance entry id that is initially set + to a random integer between 100 and 10000. +
  • Each Document has: