bigskysoftware/intercooler-js

Elements with SSE trigger do not get cleaned up when swapped out of the DOM

adamstep opened this issue · 6 comments

I have a page with the following setup:

  • The page has one ic-sse-src attribute on the body tag
  • There's a list of items, each item has a ic-trigger-on="sse:event" attribute.
  • The list itself can get swapped out using Intercooler, through a trigger elsewhere on the page.

We noticed that items removed from the document are still being triggered by SSE events. Looking at the source code, it doesn't look like we ever call removeEventListener on the event source for removed elements. This causes unexpected behaviors, not to mention memory leaks.

I can see two possible solutions to the problem:

  • In the event listener, check that sourceElement is still part of the document. If not, remove the event listener from the source at that time. This lazy cleanup would ensure correctness, but it wouldn't prevent memory leaks
  • Store the listener on the source element in a data attribute. Use MutationObserver to check if a removed node has a listener. If so, remove the listener from the event source. This would take more code, but it would prevent memory leaks.

Let me know your thoughts or preferred approaches before I continue with a fix.

1cg commented

What about adding some code to beforeSwapCleanup that looks for SSE triggers in the outgoing content and closes them?

@chg20 Using beforeSwapCleanup instead of MutationObserver would work, but I think we still need to store the added event listener on the element to properly remove it. I can try that out and update this issue if I get something working.

1cg commented

sounds good

when are you going to start working on htmx? :)

I tried it out this weekend actually :)

If this same issue affects htmx, I'm happy to submit a PR on that code too

1cg commented

Please do.

Also, you are an old hypertalk guy, right? Let me know if this interests you at all: https://hyperscript.org/

1cg commented

fixed with #322