Skip to content
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

Save a reference to the LCP and CLS targets in case they are removed from the DOM #562

Open
wants to merge 20 commits into
base: v5
Choose a base branch
from

Conversation

tunetheweb
Copy link
Member

@tunetheweb tunetheweb commented Nov 6, 2024

Fixes #561

Note this also corrects an inconsistency where lcp selector in the attribution object was labeled element rather than target (like CLS and INP).

@tunetheweb
Copy link
Member Author

Test here: https://disappearing-cwv-node.glitch.me/index.html

Maybe we should add this to the test suite?
And maybe we should do this for CLS too?

Copy link
Member

@philipwalton philipwalton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should add this to the test suite?

Yes, I think we want a test for this behavior. It should be possible to test.

src/attribution/onLCP.ts Outdated Show resolved Hide resolved
src/attribution/onLCP.ts Outdated Show resolved Hide resolved
@tunetheweb tunetheweb changed the title Save a reference to the LCP element in case it is removed from the DOM Save a reference to the LCP and CLS elements in case they are removed from the DOM Nov 6, 2024
@tunetheweb
Copy link
Member Author

Yes, I think we want a test for this behavior. It should be possible to test.

Added tests for LCP, CLS and even the INP scenario added in #477

@dmitiiv
Copy link

dmitiiv commented Nov 7, 2024

Can you add the same logic for metric -> lcpEntry -> element?

@tunetheweb
Copy link
Member Author

tunetheweb commented Nov 7, 2024

I've added it as a new attribution.elementNode entry as we don't want to amend the actual entry.

README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
src/attribution/onCLS.ts Outdated Show resolved Hide resolved
src/attribution/onLCP.ts Outdated Show resolved Hide resolved
src/types/lcp.ts Outdated Show resolved Hide resolved
src/types/lcp.ts Outdated Show resolved Hide resolved
@tunetheweb tunetheweb changed the title Save a reference to the LCP and CLS elements in case they are removed from the DOM Save a reference to the LCP and CLS targets in case they are removed from the DOM Dec 16, 2024
@tunetheweb
Copy link
Member Author

@dmitiiv there's a request not to save the full element (see #580) but instead just the target due to the amount of memory that can be taken up. This makes reporting the element back kinda pointless (since it can be got from the lcp entry).

Would the selector be sufficient for you without the element?

@dmitiiv
Copy link

dmitiiv commented Dec 16, 2024

@tunetheweb Yes, I've seen the issue. Removing the element (without saving) makes the fix almost useless for the purpose of obtaining information about the target element in a Single Page Application (SPA). It is critical to keep statistics without losing the details of the problem. However, if we still have an element selector, it could allow us to safely retain the necessary information.
Briefly, yes its not that was expected but better if we don't have even a selector

@tunetheweb
Copy link
Member Author

Yes we would still look to save the element selector (and in fact this would be the better selector since it would be calculated while the element is still part of the DOM, rather than once it's been removed).

@philipwalton
Copy link
Member

philipwalton commented Dec 17, 2024

There are a number of tradeoffs being made here, balancing different needs from various users of this library.

I think the root of all these issues is that currently the library has its own internal getSelector() function that users cannot modify, so some users have asked for the library to expose the underlying DOM element as a solution. This gives users more flexibility, but it comes at a cost of requiring the library to store strong references to these DOM elements for all users, even users that don't need this functionality (because the default selector logic works fine for them).

I wonder if instead of the library making decisions about these tradeoffs, it would be better to give users full control, in the form of letting them customize the target selector generation logic.

Perhaps something like an option to pass their own getTargetSelector function:

onLCP(metricCallback, { 
  getTargetSelector: (element) => {
    // Users can add whatever logic they want to generate a selector,
    // some other identifier, or even just return the element itself.
    return myCustomStringifyLogic(element);
  }
});

This option would be available for all metric functions in the attribution build.


Regarding whether to run the getSelector() logic at reporting time or at the time when the entry is dispatched, there are also tradeoffs here. I don't think the getSelector() is slow or anything, but it does have to traverse up the DOM tree for each element, which (depending on the size of the DOM and the number of page interactions, layout shifts, etc.) could result in a lot of processing. That's the main reason I originally choose to generate the selector at reporting time.

While we could make this change and always calculate at entry-dispatch time, any users who need this behavior can already get it by using the reportAllChanges option, so this change would impose the slower behavior on all users, even those who don't need it.

To be clear, I'm not necessarily opposed to this change, I just want to make sure we're thinking about all of the trade offs before making a decision that impacts all users of the library.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants