22

In a Single Page Application, elements are often removed and replaced. On elements that are removed from the DOM there could be an IntersectionObserver(or any other kind)

For events I never bothered to care because they are bound and triggered on the target so they should be rather harmless to keep. For the IntersectionObserver I'm somewhat worried all instances are checked on any view change.

Consider the following part of my Lazy.ts

setIntersectionObserver(config:LazyConfig)
{
  let intersectionObserver = new IntersectionObserver((entries:Array<IntersectionObserverEntry>) => {
    for (let entry of entries) {
      if (entry.isIntersecting) {
        this.lazyLoad(config);
        intersectionObserver.disconnect();
        mutationOberserver.disconnect();
      }
    }
  }, {
    threshold: 0,
    rootMargin: `${config.offset}px`,
  });
  intersectionObserver.observe(config.element);

  let mutationOberserver = new MutationObserver((entries:Array<MutationRecord>) => {
    if (
      entries[0].removedNodes &&
      document.body.contains(config.element) === false
    ) {
      intersectionObserver.disconnect();
      mutationOberserver.disconnect();
    }
  });

  mutationOberserver.observe(document.body, {
    childList: true,
    subtree: true
  });
}

Is the bottom part (mutationOberserver) useless or not? It might even harm performance because of the many checks on document.body.

Usually I would just assume garbage collection will do its job just fine, but the script keeps an array of references to all Attached elements. And that array does not get cleaned (and can't be cleaned without the Observers)

--Edit--

It does not get "deleted" (or at least not in 10 seconds) https://jsfiddle.net/c1sgdcrd/ So, the question still stands wether it's better to just keep it in memory or actively use the MutationObserver and disconnect it.

René
  • 6,006
  • 3
  • 22
  • 40
  • 5
    https://w3c.github.io/IntersectionObserver/#lifetime – wOxxOm Dec 22 '17 at 14:12
  • @wOxxOm I wasn't sure about "deleted" because of the reference I keep. It's only removed from the document and not permanently deleted. but I suppose that counts the same for IntersectionObserver? – René Dec 22 '17 at 14:32
  • 1
    I think `deleted` means garbage-collected, not `detached` so it's a no in your case. Anyway, the spec and the API itself are at PoC level so you might need to clarify this aspect with the spec authors. – wOxxOm Dec 22 '17 at 14:54
  • Is it possible to change the script to use a WeakMap of the elements, instead of an Array? Then the elements could be garbage collected, and the IntersectionObserver would stop observing them as they were collected. – FellowMD Mar 18 '18 at 21:17
  • I was getting weird bugs when I deleted elements that were being observed, and added new ones in their place. My callback would fire, and I'd see the old targets in my list of entries, but they had no parentNode or position information. Once I `unobserved()` those elements before deleting them, the issues went away. – bryanbraun Aug 15 '19 at 04:31
  • In Firefox 93, garbage collection doesn’t work right away, and there are entries with removed elements; cleanly calling `unobserve` fixed it, but it’d be nice if discarding an element would deregister it with observers. Maybe sometime. – dakab Oct 12 '21 at 18:11
  • 1
    Not sure if it is 100% same case, but there is https://github.com/w3c/IntersectionObserver/issues/474 with links to browser bugs, which were fixed, so the answer is "No need" – Viktor Mukhachev May 26 '23 at 09:50

1 Answers1

9

I can't find an official post yet, but I'm going to assume it's the same as MutationObservers, which is that garbage collection is supposed to handle the removing once the DOM element is removed. See https://dom.spec.whatwg.org/#garbage-collection

I also posted the answer for MOs here: Should MutationObservers be removed/disconnected when the attached DOM node is removed like removeEventListener for events?

Modular
  • 6,440
  • 2
  • 35
  • 38