fix(browser): Keep the best element name captured for an interaction - #24272
fix(browser): Keep the best element name captured for an interaction#24272logaretm wants to merge 1 commit into
Conversation
size-limit report 📦
|
e5cf7e0 to
f46520d
Compare
f46520d to
f1b239d
Compare
f1b239d to
5e012d5
Compare
|
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 5e012d5. Configure here.
The INP element-name cache is keyed by the rounded event timestamp and every event of one interaction shares that timestamp, so the last write won. When a click handler swaps out the element under the cursor, the browser then fires `pointerover`/`mouseover` for the new element carrying that same timestamp, and those overwrote the cached name. An INP span for a click that navigated away was named after the post-mutation DOM rather than the element that was clicked. The earliest name in the sequence is the one that describes the element actually interacted with, so it wins. Names that describe nothing are not cached at all: not every event in a sequence has a describable target, and one that doesn't would otherwise claim the timestamp and leave the span named `<unknown>`.
5e012d5 to
7ec1d7e
Compare
| // Every event of one interaction shares a timestamp, and so do the `pointerover`/`mouseover` | ||
| // the browser fires afterwards when a handler swaps out the element under the cursor. Those | ||
| // arrive last and describe the new DOM, so keeping the first usable name is what pins the entry |
There was a problem hiding this comment.
Bug: Two separate interactions within the same millisecond can be assigned the same element name, as they round to the same timestamp key in ELEMENT_NAME_TIMESTAMP_MAP, causing incorrect attribution.
Severity: LOW
Suggested Fix
To prevent collisions between different interactions, the cache key should be more specific. Instead of relying solely on a rounded timestamp, consider a composite key that includes the interactionId or scope the element name cache on a per-interaction basis. This would ensure that element names from one interaction cannot be accidentally used for another.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: packages/browser-utils/src/web-vitals/inp.ts#L96-L98
Potential issue: The code uses `Math.round(event.timeStamp)` as a key to cache element
names in `ELEMENT_NAME_TIMESTAMP_MAP`. If two distinct user interactions occur within
the same millisecond, they can round to the same integer key. The
`ELEMENT_NAME_TIMESTAMP_MAP.has(timestamp)` check prevents the second interaction's
element name from being stored. Consequently, when `resolveElementNameFromEntry` is
called for the second interaction, it incorrectly retrieves the cached element name from
the first interaction, leading to incorrect analytics data. While this scenario is rare,
it represents a logical flaw where separate interactions can have their data
misattributed.
Did we get this right? 👍 / 👎 to inform future reviews.
I noticed this while writing tests for the soft navs in #24273 and this changes the logic to grab the first available name and doesn't overwrite it with other candidates. again this was all best effort from the get go, so this adjusts this a bit more.
This only reproduces on Chromium 151+. Older versions happen to round the follow-up events to a different millisecond, which is why nothing caught it so far.
In a follow up when 153 is released we can rely on
targetSelectorproperty to get us the element name reliably.