question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Feature Request: Add `removeEventListener`/`unobserve` equivalent

See original GitHub issue

Currently every invocation creates a new PerformanceObserver that never unobserves so there’s no way to remove a handler. It’d be nice to be able to remove old listeners.

EDIT: This affects the web vitals extension which leaks listeners on every activation of tab. I’m fixing over there, but this seems generally useful too 😃

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:11 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
patrickhulcecommented, Jul 7, 2020

That certainly makes sense from the CrUX stakeholder “don’t move the goalposts” perspective 👍

As a site owner though, I’m not sure I share this motivation in my own measurements. I’m not interested in my site’s performance as a measure of how frequently my users hit the back button 😃 That’s certainly a separately useful insight, but being forced to count this as a separate navigation via the canonical web-vitals API still feels odd. Knowing this, the first thing I’m going to try to do when analyzing my site’s performance is going to be excluding these 0s skewing the distribution and anyone that isn’t aware of this distinction is probably going to get a falsely rosy picture of their performance because of how counterintuitive it is.

The rabbit hole of “constructing a site that encourages back button interaction to goose CrUX numbers” is probably something not worth exploring here but does add another arrow in my “RUM is too complex to boil down to aggregate thresholds” quiver 😆

1reaction
philipwaltoncommented, Aug 5, 2020

I feel like this thread has drifted a little from the original intent, so I’ll try to refocus here 😃

Yes, let’s refocus 😃

I’m concerned that developers can be trusted enough to know they have to do this in order to fully understand the output of this library but they can’t be trusted enough to know how to use a removeEventListener function with documentation 😕

I wouldn’t say my concern is that they can’t be trusted to use a removeEventListener function with documentation, my concern is that I’m not convinced there’s a strong enough need to have such a function.

For FCP, FID, and LCP, the library already disconnects the PerformanceObserver once the final value is known, but it doesn’t let users unobserve the callback since we’ll likely need to invoke it again after a bfcache load. And for CLS we don’t actually want people to disconnect the observer, since if they do they’ll be measuring CLS incorrectly.

(EDIT: hmm, looks like only FID disconnects the observer, but that’s a bug, I’ll update the others to do so too)

I definitely see someone wrapping this in a react useEffect hook and getting lots of accidental copies beaconed unnecessarily. At the very least if this is a hard line in the sand and the official position is that removing the installed listeners should be impossible with this library then IMO the docs should come with a big warning to not call these functions more than once.

Sure, I can see how this could be misused, but presumably such a situation would be a mistake, and adding an unobserve function wouldn’t necessarily prevent mistakes like that. Also, I don’t think there’s a valid use case for calling these functions and then disconnecting all of them in a useEffect hook.

All this being said, I’d be happy to add clarifying language indicating that these functions should not be called more than once per page load. (And we’ll definitely need clarifying language once the bfcache functionality is added.)

In the end, I want this library to just “do the right thing” as much as possible since we’ve learned over and over again from lots of experience that people don’t thoroughly read the documentation, and there are lots of edge cases that are easy to overlook. For example, with LCP it’s clearly documented in the code sample that people measuring LCP should ignore cases where the tab was loaded in the background, yet 100% of the RUM libraries I’ve audited since we announced Web Vitals have missed this. And these are not random developers, these are folks whose business is building RUM products. So, as a results, I’ve chosen to keep the API surface for the library as small as possible.

Read more comments on GitHub >

github_iconTop Results From Across the Web

EventTarget.removeEventListener() - Web APIs | MDN
The removeEventListener() method of the EventTarget interface removes an event listener previously registered with EventTarget.
Read more >
remove event listener without knowing what the call back ...
As an alternative, you can try something like this: element.addEventListener('click', (e) => { e.stopImmediatePropagation(); ...
Read more >
An Explanation of How the Intersection Observer Watches
These methods provide the ability to watch and unwatch target elements, but there's no way to change the options passed to the observer...
Read more >
"removeEventListener" | Can I use... Support tables for HTML5 ...
"Can I use" provides up-to-date browser support tables for support of front-end web technologies on desktop and mobile web browsers.
Read more >
JavaScript Event Listeners Ultimate Guide
The removeEventListener function is a simple function that you can call on an element to remove an event listener that was previously added...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found