w3c / event-timing

A proposal for an Event Timing specification.
https://w3c.github.io/event-timing/
Other
44 stars 13 forks source link

Proposal: DOM event identifier which can map to EventTimingPerformance entry #108

Open nhelfman opened 3 years ago

nhelfman commented 3 years ago

When using event timing API to track responsiveness it is sometimes important to track specific user actions. For example: clicking on a certain UI element which in response modifies the UI. To do that we need to be able to match between DOM event passed to the listening event handler and the event timing entry reported by the PerformanceObserver callback.

A way to do that is by matching the DOMEvent.timeStamp and entry.startTime which according to the spec refer to the same time.

This unfortunately requires keeping all DOM events in a structure with mapping to the user action identifier which will allow later matching in the async observer callback. It also require maintaining the lifecycle of the kept DOM events which complicates the solution.

Proposal: add ability to add arbitrary identifier string to DOM events which will also be reported as part of PerformanceEventTiming entry.

For example:

elemButton1.addEventListener('click', e => {
  e.identifier= 'elemButton1MenuOpen';
});

// in PerformanceObserver callback
// ...
console.log(`user action: ${entry.identifier)} duration: ${entry.duration}`;

It can be possibly be argued that since PerformanceEventTiming include the target element the proposal is not necessary since we can always match by the target DOM element id (or other attribute). However, in some apps this will not be sufficient since the actual user action depends not only on the element that received the event but also on the app in memory state and will be computed at runtime (perhaps based on the position the element was interacted with).

mmocny commented 2 years ago

I agree with the importance of this use case, and have heard requests for similar. I think it would be useful to link handler-based measures to PerformanceEventTiming.


I worry about the specific proposal of supporting attaching an identifier from the handler, especially for cases where there are multiple handlers. While the application code may consider the same event to have multiple identifiers for different reasons, Event Timing merges into a single report. Exposing a list of identifiers starts to get awkward.


I think the idea of using the timeStamp / startTime as a type of identifier is interesting. It has the additional advantage of also grouping a range of event types together, that are a direct result of the same hardware event.

I think the concern you raise is that it can be a lot of temporary accounting required... but is that necessarily true? Presumably you could filter only to specific event types, and you don't need to keep the whole DOM event, just the timeStamp and whatever extra metadata you desire?

Unfortunately I didn't understand the last parts about target and application state. My understanding is that target and application state would be constant given the same event (same timeStamp)?


If timeStamp is not a sufficiently useful identifier, perhaps we can consider exposing an eventId, akin to interactionId, but chosen earlier (before dispatching events)?

nhelfman commented 2 years ago

@mmocny I'll try to address some of your question and provide clarifications.

The issue is mainly about being able to provide attribution of specific user interaction by using Event Timing. Specific user interaction would mean interaction with a specific UI flow. For example, "user clicked on bold button in the top menu bar". It expands on what Event Timing API currently provides which is "user clicked on something".


I think the idea of using the timeStamp / startTime as a type of identifier is interesting. It has the additional advantage of also grouping a range of event types together, that are a direct result of the same hardware event.

I mentioned using timestamp for an identifier as a negative example of how it can be done. It feels more like a hack and requires accounting logic. In addition, it is currently possible for more that 1 event to have the same timestamp (see a bug we filed on this https://bugs.chromium.org/p/chromium/issues/detail?id=1315015) which makes it impossible to differentiate between events.


Unfortunately I didn't understand the last parts about target and application state. My understanding is that target and application state would be constant given the same event (same timeStamp)?

The target comment - I tried to use it as a counter argument for my request of adding an identifier to the event and then show why it is not a valid counter argument. When trying to address the requirement of attribution we considered at first using the EventTimingPerformanceEntry.target as an indicator to what specific UI flow was executed. However, we soon realized that several flows use the same DOM element to trigger separate flows, based on the app state (e.g., keypress handler which moves selection up or down, or initiate editing UI depending on the pressed key) so using the target is not sufficient for this purpose.


If timeStamp is not a sufficiently useful identifier, perhaps we can consider exposing an eventId, akin to interactionId, but chosen earlier (before dispatching events)?

IIRC we discussed this idea before as part of the WebPerf WG meeting. A unique eventId will certainly address one aspect of the concern for avoid using timestamps. However, it will not address the main requirement of being able to easily attribute interaction to specific flow. It will still require a custom mapping between the eventId and the label for the specific user flow. Ideally developers can easily annotate the DOM events passed to event handlers and the annotation can be passed to the EventTimingPerformanceEntry for later processing. I agree a single string property has an issue in case another handler overrides it (this is a valid case that will certainly happen). How about having a string Set or array instead?

mmocny commented 1 year ago

Just a few followups, not all are directly related to your specific proposal, but are related to matching up Events (dispatch) with Event Timing (api):

mmocny commented 2 months ago

I wonder if this issue could also be addressed by the work @noamr is working on for "tracing" changes. The goals there are to allow developers to provide hints about scripts/tasks and which could be picked up by entries like event timing.

https://github.com/w3c/long-animation-frames/issues/3