-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add navigationId to PerformanceEntry #192
Changes from 8 commits
db40939
3248985
cb8dd26
6e5497e
3adcc6a
564c3cb
ec0e067
1497e2a
8e34f8f
771922d
1550c7d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -59,6 +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`: 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`. | ||
|
@@ -150,6 +151,20 @@ 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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: back-forward cache |
||
a document wich they have previously navigated away from. The web has also seen a rise in | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/wich/which/ |
||
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. | ||
yoavweiss marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/links/ties/ |
||
navigation entry which had occurred when the entry was generated. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/when/before/ ? |
||
|
||
# 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. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -67,6 +67,9 @@ | |
</li> | ||
<li>Exposes {{PerformanceEntry}} in Web Workers [[WORKERS]]; | ||
</li> | ||
<li>Formalizes support for multiple navigation events over a document's | ||
lifetime. | ||
</li> | ||
<li>Adds support for {{PerformanceObserver}}. | ||
</li> | ||
</ul> | ||
|
@@ -244,6 +247,12 @@ <h2><dfn>Performance Timeline</dfn></h2> | |
</ul> | ||
</li> | ||
</ul> | ||
<p>Each <a>Document</a> has:</p> | ||
<ul> | ||
<li>a <dfn>most recent navigation</dfn>, which is a <a>PerformanceEntry</a>, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/a/A/ |
||
initially unset. | ||
</li> | ||
</ul> | ||
<p>In order to get the <dfn>relevant performance entry tuple</dfn>, given | ||
<var>entryType</var> and <var>globalObject</var> as input, run the | ||
following steps:</p> | ||
|
@@ -305,6 +314,7 @@ <h2>The <dfn>PerformanceEntry</dfn> interface</h2> | |
readonly attribute DOMString entryType; | ||
readonly attribute DOMHighResTimeStamp startTime; | ||
readonly attribute DOMHighResTimeStamp duration; | ||
readonly attribute DOMString navigationId; | ||
[Default] object toJSON(); | ||
};</pre> | ||
<dl> | ||
|
@@ -341,6 +351,10 @@ <h2>The <dfn>PerformanceEntry</dfn> interface</h2> | |
duration concept doesn't apply, a performance metric may choose to | ||
return a `duration` of <code>0</code>. | ||
</dd> | ||
<dt><dfn>navigationId</dfn></dt> | ||
<dd> | ||
This attribute MUST return the value of <a>this</a>'s <a>navigationId</a>. | ||
</dd> | ||
</dl> | ||
<p>When <dfn>toJSON</dfn> is called, run [[WebIDL]]'s <a>default toJSON | ||
steps</a>.</p> | ||
|
@@ -584,6 +598,7 @@ <h2><dfn>PerformanceObserverEntryList</dfn> interface</h2> | |
PerformanceEntryList getEntries(); | ||
PerformanceEntryList getEntriesByType (DOMString type); | ||
PerformanceEntryList getEntriesByName (DOMString name, optional DOMString type); | ||
PerformanceEntryList getEntriesByNavigationId (DOMString navigationId); | ||
}; | ||
</pre> | ||
<p>Each {{PerformanceObserverEntryList}} object has an associated | ||
|
@@ -592,24 +607,34 @@ <h2><dfn>PerformanceObserverEntryList</dfn> interface</h2> | |
<section> | ||
<h2><dfn>getEntries()</dfn> method</h2> | ||
<p>Returns a <a>PerformanceEntryList</a> object returned by <a>filter | ||
buffer by name and type</a> algorithm with <a>this</a>'s <a>entry list</a>, | ||
<var>name</var> and <var>type</var> set to <code>null</code>.</p> | ||
buffer</a> algorithm with <a>this</a>'s <a>entry list</a>, | ||
<var>name</var>, <var>type</var> and <var>navigationId</var> set to | ||
<code>null</code>.</p> | ||
</section> | ||
<section> | ||
<h2><dfn>getEntriesByType()</dfn> method</h2> | ||
<p>Returns a <a>PerformanceEntryList</a> object returned by <a>filter | ||
buffer by name and type</a> algorithm with <a>this</a>'s <a>entry list</a>, | ||
<var>name</var> set to <code>null</code>, and <var>type</var> set to the | ||
method's input <code>type</code> parameter.</p> | ||
buffer</a> algorithm with <a>this</a>'s <a>entry list</a>, | ||
<var>name</var> set to <code>null</code>, <var>type</var> set to the | ||
method's input <code>type</code> parameter, and <var>navigationId</var> | ||
set to <code>null</code>.</p> | ||
</section> | ||
<section> | ||
<h2><dfn>getEntriesByName()</dfn> method</h2> | ||
<p>Returns a <a>PerformanceEntryList</a> object returned by <a>filter | ||
buffer by name and type</a> algorithm with <a>this</a>'s <a>entry list</a>, | ||
buffer</a> algorithm with <a>this</a>'s <a>entry list</a>, | ||
<var>name</var> set to the method input <code>name</code> parameter, and | ||
<var>type</var> set to <code>null</code> if optional `entryType` is omitted, | ||
or set to the method's input <code>type</code> parameter otherwise.</p> | ||
</section> | ||
<section> | ||
<h2><dfn>getEntriesByNavigationId()</dfn> method</h2> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did we discuss creation of a dedicated filter, compared to applying a JS filter on |
||
<p>Returns a <a>PerformanceEntryList</a> object returned by <a>filter | ||
buffer</a> algorithm with <a>this</a>'s <a>entry list</a>, | ||
<var>name</var> and <var>type</var> set to <code>null</code>, and | ||
<var>navigationId</var> set to the method's input | ||
<code>navigationId</code> parameter.</p> | ||
</section> | ||
</section> | ||
</section> | ||
<section> | ||
|
@@ -669,6 +694,15 @@ <h2>Queue a <code>PerformanceEntry</code></h2> | |
<li>Let <var>relevantGlobal</var> be <var>newEntry</var>'s <a>relevant | ||
global object</a>. | ||
</li> | ||
<li>If <var>relevantGlobal</var> has an [=associated document=]: | ||
<ol> | ||
<li>Set <var>newEntry</var>'s <a | ||
data-lt="PerformanceEntry.navigationId">navigationId</a> to the value of | ||
<var>relevantGlobal</var>'s [=associated document=]'s [=most recent navigation=]'s {{PerformanceEntry/navigationId}}.</li> | ||
</ol> | ||
</li> | ||
<li>Otherwise, set <var>newEntry</var>'s <a | ||
data-lt="PerformanceEntry.navigationId">navigationId</a> to null.</li> | ||
<li>For each <a>registered performance observer</a> <var>regObs</var> in | ||
<var>relevantGlobal</var>'s <a>list of registered performance observer objects</a>: | ||
<ol> | ||
|
@@ -714,6 +748,24 @@ <h2>Queue a <code>PerformanceEntry</code></h2> | |
</li> | ||
</ol> | ||
</section> | ||
<section data-link-for="PerformanceObserver"> | ||
<h2>Queue a navigation <code>PerformanceEntry</code></h2> | ||
<p>To <dfn class="export">queue a navigation PerformanceEntry</dfn> (<var>newEntry</var>), run | ||
these steps:</p> | ||
<ol> | ||
<li>Let <var>navigationId</var> be the result of running <a>generate a navigationId</a> for <var>newEntry</var>.</li> | ||
<li>Let <var>relevantGlobal</var> be <var>newEntry</var>'s <a>relevant | ||
global object</a>. | ||
</li> | ||
<li>Set <var>newEntry</var>'s {{PerformanceEntry/navigationId}} to <var>navigationId</var>.</li> | ||
<li>If <var>relevantGlobal</var> has an [=associated document=]: | ||
<ol> | ||
<li>Set <var>relevantGlobal</var>'s [=associated document=]'s [=most recent navigation=] to <var>newEntry</var>.</li> | ||
</ol> | ||
</li> | ||
<li><a>Queue a PerformanceEntry</a> with <var>newEntry</var> as input.</li> | ||
</ol> | ||
</section> | ||
<section data-link-for="PerformanceObserver"> | ||
<h2>Queue the PerformanceObserver task</h2> | ||
<p>When asked to <dfn>queue the PerformanceObserver task</dfn>, given | ||
|
@@ -826,7 +878,7 @@ <h2>Filter buffer map by name and type</h2> | |
continue to the next <var>tuple</var>. | ||
</li> | ||
<li>Let <var>entries</var> be the result of running <a>filter | ||
buffer by name and type</a> with <var>buffer</var>, <var>name</var> | ||
buffer</a> with <var>buffer</var>, <var>name</var> | ||
and <var>type</var> as inputs. | ||
</li> | ||
<li>For each <var>entry</var> in <var>entries</var>, | ||
|
@@ -840,10 +892,10 @@ <h2>Filter buffer map by name and type</h2> | |
</ol> | ||
</section> | ||
<section data-link-for="PerformanceEntry"> | ||
<h2>Filter buffer by name and type</h2> | ||
<p>When asked to run the <dfn>filter buffer by name and type</dfn> | ||
algorithm, with <var>buffer</var>, <var>name</var>, and <var>type</var> | ||
as inputs, run the following steps:</p> | ||
<h2>Filter buffer</h2> | ||
<p>When asked to run the <dfn>filter buffer</dfn> | ||
algorithm, with <var>buffer</var>, <var>name</var>, <var>type</var>, and | ||
<var>navigationId</var> as inputs, run the following steps:</p> | ||
<ol> | ||
<li>Let <var>result</var> be an initially empty <a>list</a>. | ||
</li> | ||
|
@@ -858,6 +910,12 @@ <h2>Filter buffer by name and type</h2> | |
<a data-cite=INFRA#string-is>identical to</a> <var>entry</var>'s | ||
<code>name</code> attribute, continue to next <var>entry</var>. | ||
</li> | ||
<li>If <var>navigationId</var> is not null and if | ||
<var>navigationId</var> is not | ||
<a data-cite=INFRA#string-is>identical to</a> <var>entry</var>'s | ||
<code>navigationId</code> attribute, continue to next | ||
<var>entry</var>. | ||
</li> | ||
<li>[=list/append=] <var>entry</var> to <var>result</var>.</li> | ||
</ol> | ||
</li> | ||
|
@@ -883,6 +941,18 @@ <h2>Determine if a performance entry buffer is full</h2> | |
<li>Return true.</li> | ||
</ol> | ||
</section> | ||
<section data-link-for="PerformanceEntry"> | ||
<h2>Generate a navigationId</h2> | ||
<p>When asked to <dfn class="export">generate a navigationId</dfn> for a | ||
<a>PerformanceEntry</a> <var>entry</a>, run the following steps:</p> | ||
<ol> | ||
<li>Let <var>type</var> be <var>entry</var>'s <a>entryType</a>.</li> | ||
<li>Let <var>startTime</var> be <var>entry</var>'s <a>startTime</a>. | ||
</li> | ||
<li>Return the [=string/concatenation=] of « <var>type</var>, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know we initially talked about a UUID, but this may be equivalent. A few things that may hamper that:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Makes sense! FWIW, when working on resource timing initiator (which uses a similar ID concept), we got feedback that it might be more ergonomic to use an object rather than a concatenated string. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we run into problems with object equality, if we use a structured object? Specifically, are there issues around key order or numeric precision, or just the fact that object equality is often conflated with object identity? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Discussed at the WG; there probably are issues with identity/equality here, and a string has better comparison behaviour, as long as we ensure it is unique. |
||
<var>time</var> » using U+002D HYPHEN-MINUS.</li> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. concatenation is defined for a list of strings, so I think you need to convert the timestamp to a string first. |
||
</ol> | ||
</section> | ||
</section> | ||
<section id="privacy"> | ||
<h3>Privacy Considerations</h3> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
integer?