There are three ways to add event listeners to a host element
readyconnectedCallback (requires removal in disconnectedCallback)Which is the best way? Are there any memory leak issues for (1) and (2)?
I hope there would be some documentation on this topic.
Thanks for the question, I'm working on the docs for lit-element :) What's in my draft at the moment is basically this
window), you should add the listener in connectedCallback and remove it in disconnectedCallback This is based on the Polymer docs: https://www.polymer-project.org/3.0/docs/devguide/events. My understanding is that it's the same for lit-element, though I'll confirm this info before docs get published.
Can you explain the third point a bit? Not sure I'm getting why that is the case, would be great to understand.
As I understand it, constructor doesn't care about DOM whereas connectedCallback is after DOM attachment, so why would it matter for anything going to anything else than the actual component/children (DOM) to put it into connectedCallback?
Can we get a preview somehow? There's very little info on on LitElement at the moment.
Docs quality can make or break a project 100%
@AndreasGalster the following is my attempt at an explanation. Maybe @TimvdLippe might be able to correct me or clarify here.
I believe the reasoning for this recommendation is to do with removing the event listener in disconnectedCallback so that garbage collection can be done. To illustrate, here are a couple of scenarios:
Scenario 1
Scenario 2
In Scenario 2, I am not sure when or how the memory in the scope created by the event listener on Window would get released. My understanding is that garbage collection works differently in different browsers and this scenario might not be good for memory management.
Scenario 2.A
connectedCallback fires, event listener is added to WindowdisconnectedCallback fires, event listener is removed from Window, memory is freed up and all is wellThe recommendation to use disconnectedCallback to remove event listeners added to things that aren't MyElement or its children seems clear in this scenario. As for why you would add it in connectedCallback instead of the constructor in this scenario, I can't say for sure, but it does seem nice and clean to do stuff in connectedCallback if you're going to undo it in disconnectedCallback. Maybe a scenario like the following would make it more relevant:
Scenario 3
connectedCallback fires, event listener is added to ParentThingdisconnectedCallback fires, event listener is removed from ParentThingconnectedCallback fires again, etc@aadamsx I agree, and will try to publish a preview as soon as I have enough content :)
@katejeffreys That sounds about right! :smile: I think the key scenario is 2.A here, where the usage of disconnectedcallback is crucial to prevent memory leaks.
Isn't there one more scenario where an event listener gets added - namely using on-my-custom-event on an element in the html template string literal returned from the _render function. Does this get removed automatically if the host element disconnects from the dom? Does this still work inside of loops?
It seems to me that this approach is easier than trying to add one via addEventListener
@akc42 The on-* syntax is part of lit-html. This is sugar for calling addEventListener on these nodes. These listeners are therefore automatically cleaned up when the corresponding node is removed from the DOM.
@TimvdLippe not anymore, it is @ now, like @change=${...}
I'd really love to see the readme.md updated with an actual useful example of event binding. Right now the only example is a @click handler that does nothing but call console.log. How is that helpful? Who is writing event handlers inline? Pretty much every event handler I write is written as a class method, but there's no documentation at all (nor any official examples) that show this most basic of cases. I understand that this is a WIP and that the readme was most likely written by developers rather than a technical doc writer, but that's no excuse for picking such an unhelpful example case.
Edit: Man, that was fast! Thanks for the update!
I edited my previous comment, but since that won't trigger any notifications, I'll copy what I added here: Thanks for the quick update with the much more useful event handler example!
@TimvdLippe not anymore, it is
@now, like@change=${...}
Had to do quite a bit of digging to find this. Thanks for the clarification. Would love to see an example for this in the docs.
@jeremyrader The docs are work in progress, and coming soon. If you're looking for some code examples maybe this is helpful to you.
If you need to imperatively add a listener to rendered children, it must be added in firstUpdated or later, IIRC.
Most helpful comment
Thanks for the question, I'm working on the docs for lit-element :) What's in my draft at the moment is basically this
window), you should add the listener inconnectedCallbackand remove it indisconnectedCallbackThis is based on the Polymer docs: https://www.polymer-project.org/3.0/docs/devguide/events. My understanding is that it's the same for lit-element, though I'll confirm this info before docs get published.