GoogleChrome / web-vitals

Essential metrics for a healthy site.
https://web.dev/vitals
Apache License 2.0
7.62k stars 418 forks source link

INP Loses Target Element After SPA Route Change #567

Closed dmitiiv closed 2 days ago

dmitiiv commented 1 week ago

How to reproduce

Not always, but systematically, there is a loss of the target element and selector. At the same time, firstEntryWithTarget?.target == undefined and interactionTargetMap contains an element by interactionId, but firstEntry.interactionId differs from the one saved in interactionTargetMap and is always greater than it by 7

tunetheweb commented 4 days ago

Can you create an example to show the issue here?

Chrome does increment interactionids by 7 but FID should be the first interactionId for the page, so odd that it's later.

dmitiiv commented 3 days ago

I described how to reproduce the problem above. To do this, you need to create a SPA application (I used Vite + React). I generate the INP metric via select with a shift of the block DOM element. 1) I click on the select 2) I do not perform actions that may lead to a change in the visiblitystate of the page 3) In the basic application, I click on the About router change link 4) I switch between browser tabs and return to the application tab

Result :

interactionTargetMap contains the target element of the metric and it is stored by interactionId, but when performing the described actions firstEntry' is changing and the 'interactionId is incremented. At the same time, the metric object does not change (I could not catch changes in the values of value, delta, etc.), and the attribution is recalculated based on wrong firstEntry

Why do I think this is a bug:

the attribution object is formed based on the entry, which is not the reason for the next paint

if we assume that the event that occurred is correctly wiped by interactionTarget, then we lose the metric for analysis

dmitiiv commented 3 days ago

The problem is reproduced periodically, but steadily.

tunetheweb commented 3 days ago

I do not use Vite nor React. Can you point me to an existing MVP app that demonstrates the issue?

dmitiiv commented 2 days ago

I can create the MVP app and give you a link to clone the repo or if you have better idea Im ready to do.

tunetheweb commented 2 days ago

That works. I'm sure I could figure it out myself, but I always find it's best not to make assumptions and get an exact repro in case |I do something slightly different.

dmitiiv commented 2 days ago

No problem. I'm glad to help. It happens in several applications. I can't share the private repo, that I work for. But I reproduce the problem for almost default vite + react project. I prepared the repo

link to clone git@github.com:dmitiiv/inp-problem.git

repo link

Added description to README

tunetheweb commented 2 days ago

OK the issue is as follows:

  1. You click on the FIRST button (or SECOND button). This does not remove the button from the screen so by the time the browser emits the Event Timing for this, the web-vitals library can still see the node and can save the target selector and element.

  2. You click About Us link. This causes a route change and the About Us link is removed from the DOM. A few milliseconds after this, the Event Timing entry is emitted and the web-vitals library can no longer see the node, and so can't save the target selector and element.

If 1 is longer than 2 then you will get a target. If 2 is longer than 1 then you won't get a target. And, as this is a second interaction it will have a higher interactionId (by 7 since Chrome increments by 7 each time) than the first interaction.

On a fast machine they both take similar times (I'm seeing 32ms or 40ms) so they are similar but on occasion one is faster than the other. And depending which is faster you will see the intermittently. If you made the button take longer with some blocking work, then you would consistently see the target.

As noted in #477 this saving of the target is not perfect and "will not help if the element is removed before the first event entry from that interactionId is reported so is not a full solution, but will help in some cases". So to solve this we need a similar fix in the spec and then in Chrome as the library cannot do anything further than this.

TLDR this is a duplicate of #335 but the library is limited to what it can do here so we're waiting on the fix in Event Timing spec and Chrome to make further process here.