Nicolás Peña Moreno
Hongbo Song
Currently, developers can measure the latency of an event using the Event Timing API. Developers may query the duration, which returns the next paint after event handlers have run. Or they may compute the input delay, the delta between startTime (the event's timeStamp) and processingStart, which is a timestamp taken right before event is dispatched. But measuring event latency separately can’t help developers fully understand the user’s pain. When a user interacts with a web page, a user interaction (i.e. click/tap, press a key, drag) usually triggers a sequence of events. For example, when the user clicks, several events will be dispatched: pointerdown, pointerup, mousedown, mouseup, click, etc. Therefore, we propose to measure the latency of the whole user interaction by aggregating associated events’ latencies. To calculate an interaction-level latency, there should be a way to group events or to tell if two events are fired by the same user interaction. In this document we propose adding a new ID in PerformanceEventTiming named Interaction ID. Each Interaction ID will represent a unique user interaction. And events triggered by an interaction will share the same Interaction ID.
Our goal is to enable developers to group events by Interaction ID and calculate interaction level latency for a user interaction such as maximum event duration, total event duration or other customized metrics.
The latency of an interaction can be computed from the latencies of the following events:
Interaction | Events |
---|---|
keyboard | keydown, keyup |
click / tap | pointerdown, pointerup, click |
drag | pointerdown, pointerup, click |
The events in the table are chosen so that the duration of other events triggered by the interaction (like for instance keypress in the keyboard interaction) would already be captured by the durations of these events. This may prove to be confusing for developers. If it does, we could also add IDs to all PerformanceEventTiming entries corresponding to events considered to be caused by the same interaction.
The following are not goals of this proposal:
- Cover all types of interactions or events.
- Provide a new metric.
- Group performance information about events automatically.
We propose adding the Interaction ID as a new attribute in PerformanceEventTiming:
interface PerformanceEventTiming : PerformanceEntry {
// The ID for the user interaction that caused this event.
readonly attribute unsigned long interactionId;
};
If two entries correspond to events which are caused by the same user interaction, the Interaction ID of them will be the same.
The following example computes, for each interaction, the maximum event duration for all events corresponding to that interaction:
// Hashmap for storing event latencies. The key is Interaction ID.
var map = {};
const performanceObserver = new PerformanceObserver((entries) => {
for (const entry of entries.getEntries()) {
if (entry.interactionId > 0) {
// Include the event 'duration', which captures from hardware timestamp to next paint after handlers run.
const duration = entry.duration;
// Include the Interaction ID.
const interaction_id = entry.interactionId;
if (!map.has(interaction_id)) {
map[interaction_id] = [];
}
map[interaction_id].push(duration);
}
}
});
// Calculate the maximum event duration for each user interaction.
Object.entries(map).forEach(([k, v]) => {
console.log(Math.max(...v));
});
What information might this feature expose to Web sites or other parties, and for what purposes is that exposure necessary?
This feature exposes
interactionId
of events exposed to Event Timing, and it is necessary to compute interaction-level latency and compute correctly aggregated data.Do features in your specification expose the minimum amount of information necessary to enable their intended uses?
We need a way for developers to know when various PerformanceEventTiming entries correspond to the same user interaction. The
interactionId
is the simplest way to achieve this while still preserving important event-level data (such as how long event handlers take to run). This explainer does not specify the way the id would be computed, but it might be a random long number so developers don't rely on it to count interactions or infer some ordering between interactions. The random number would not be reused across frames to prevent any leaks.How do the features in your specification deal with personal information, personally-identifiable information (PII), or information derived from them?
There's not PII involved in this feature.
How do the features in your specification deal with sensitive information?
There's no sensitive information involved in this feature.
Do the features in your specification introduce new state for an origin that persists across browsing sessions?
No.
Do the features in your specification expose information about the underlying platform to origins?
No.
Does this specification allow an origin to send data to the underlying platform? No.
Do features in this specification enable access to device sensors?
No.
What data do the features in this specification expose to an origin? Please also document what data is identical to data exposed by other features, in the same or different contexts.
It exposes groups of PerformanceEventTiming entries that correspond to the same user interaction, for interactions targetting that website. The granularity is frame/Document, as with all other performance entries.
Do features in this specification enable new script execution/loading mechanisms?
No.
Do features in this specification allow an origin to access other devices?
No.
Do features in this specification allow an origin some measure of control over a user agent's native UI?
No.
What temporary identifiers do the features in this specification create or expose to the web?
The interaction id's are temporary identifiers on the user interactions that were handled by the site.
How does this specification distinguish between behavior in first-party and third-party contexts?
Since information is exposed on frame-granularity, no third-party data is exposed (i.e. the iframe data is exposed only to the iframe).
How do the features in this specification work in the context of a browser’s Private Browsing or Incognito mode?
The feature does not work differently on incognito as it does not rely on user identifier in any way.
Does this specification have both "Security Considerations" and "Privacy Considerations" sections?
Event Timing has a privacy/security section. It will be agumented with considerations on
interactionId
once that is added to the spec.Do features in your specification enable origins to downgrade default security protections?
No.
What should this questionnaire have asked?
Can't think of other relevant question.