Coming out of T295103, Intersection Observers should be explicitly disconnected to prevent memory leaks.
Acceptance criteria
- Observers are manually disconnected when elements no longer need to be observed.
Developer notes
- In the Vector repo, main.js, stickyHeader.js, scrollObserver.js are the files that invoke/use IntersectionObserver.
- We have some options to disconnect the observer using different events (i.e. beforeunload, visibilitychange, pagehide, etc).
- The MDN recommendation states:
The best event to use to signal the end of a user's session is the visibilitychange event. In browsers that don't support visibilitychange the pagehide event is the next-best alternative.
- Note though that the beforeunload and pagehide events are not reliably fired by browsers, especially on mobile (see Usage notes at pagehide and beforeunload docs). This might not be a problem now since sticky header is only a desktop feature. However, since these events have full cross-browser support, we might consider them for expediency.
- Per beforeunload docs:
There is a legitimate use case for the beforeunload event: the scenario where the user has entered unsaved data that will be lost if the page is unloaded. It is recommended that developers listen for beforeunload only in this scenario, and only when they actually have unsaved changes, so as to minimize the effect on performance.
- beforeunload (see abandoned PoC patch) is used in the reading depth instrument so there is precedent for using it but it may not be best practice to do so here.
- visibilitychange only has partial support for Safari.
- pagehide has the same issue as beforeunload re: mobile but it is compatible with back/forward cache so this might be the best approach as it is fully supported.
- Depending on what event we decide to use, implementation should be simple - add an event listener to main.js to disconnect the observer.
window.addEventListener( 'pagehide', ( event ) => { if ( !event.persisted && observer ) { observer.disconnect(); } } );