-
-
Notifications
You must be signed in to change notification settings - Fork 113
Automatic cleanup of nodes and event listeners #269
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
hyperHTML uses
That also might be your issue. If you have every single reference a different listener, i.e. an arrow function, you are trashing N times all listeners and putting back new, causing unnecessary GC. The It's a powerful mechanism you should embrace, instead of avoid, IMO. As example, I'm not too familiar with TS but if this creates a new listener each time then you have your issue: https://github.com/jiayihu/ygo/blob/master/src/components/Navbar/Navbar.ts#L29-L37 Also consider that methods called That means you don't need to make the prototype method a getter or an invoke, just call it TL;DR I cannot review your whole app but before blaming hyperHTML or HyperHTMLElement please be sure you are using these tools in the best way 😉 |
I'm not blaming hyperHTML and for the same reason I provided the small snippet, to allow us to discuss without anyone reviewing my whole app. Just trying to dig into hyperHTML. Also I'm not using an inline arrow function when rendering, so that cannot be the reason if you meant doing
I'm not holding in memory the nodes, I'm just doing the following as I added to // First render
renderRoute`<my-comp onevent=${handler1} />`
// Update: what happens to the previous nodes?
renderRoute`<another-comp onanotherevent=${handler2} />` I'm asking: what happens with the previous nodes, when you call the same binded
This declares an arrow function property for each instance of the class, not each render. Besides it's not TS specific syntax, it's the same in Babel class properties. Also it should not be an issue if previous instances are garbage-collected. |
The WeakMemory relation gets updated via Nothing is holding previous listeners, or nodes, anywhere.
Nope, nothing is held within the library, listeners speaking, but maybe the GC takes longer than it should to understand it can trash private variables used to remember the previous value of any attribute, including listeners? https://github.com/WebReflection/hyperHTML/blob/master/index.js#L1087-L1093 The issue is that there's only one holder of that scope, which is here, but we're back to the previous dance, so that when the context reference is updated, the previous
Accordingly to the code, that's exactly what happens. But if you have related (wired) same objects with more templates then you might have in memory more than you think, to have the render of each wire be ready when needed. |
P.S. how about you try with this instead ? no arrow, no need for it. Maybe it'll improve already your stats. handleClick(event: MouseEvent) {
event.preventDefault();
const anchorEl = event.target! as HTMLAnchorElement;
const dispatchedEvent: RouteChangeEvent = new CustomEvent('routeChange', {
detail: { route: anchorEl.pathname } // `href` property includes the host
});
this.dispatchEvent(dispatchedEvent);
} |
I'm pretty sure I carefully used
I've also read your article about
As far as Anyway I'm planning to dive into the source code in the next days, so I'll come back if I find something interesting. Thanks for pointing me where to start looking for. |
You keep not understanding that every method named with handleXXXX automatically does that binding for you so it's not about It binds it already for you, you don't need instance methods for that, it's done regardless. I hope this is cleaner now, so ... how about you try this? handleClick(event: MouseEvent) {
event.preventDefault();
const anchorEl = event.target! as HTMLAnchorElement;
const dispatchedEvent: RouteChangeEvent = new CustomEvent('routeChange', {
detail: { route: anchorEl.pathname } // `href` property includes the host
});
this.dispatchEvent(dispatchedEvent);
} instead of this ? handleClick = (event: MouseEvent) => {
// THIS IS NOT NEEDED 'CAUSE IT'S CALLED handleClick
};
You can easily go Θ(1 + u) where u is usage, not the number of instances, neither the number of methods, since it's a getter. All you need to do is already explained but it seems you are not getting what I am saying. |
Just in case you are misunderstanding the difference, you don't have to pass You have nothing to lose, only to gain in terms of operations, memory, and performance using I won't go through this again though, 'cause I am sure it's clear now what |
Yup I was misunderstanding buuut: I tried once and |
I honestly don't understand. I've been writing HyperHTMLElement all the time because that's what you use in that card games and all the links were pointing at that one. Here how is life with HyperHTMLElement components:
|
class HyperWelcome extends HyperHTMLElement {
handleClick() { console.log(this.tagName); }
handleInput() { console.log(this.tagName); }
render() {
this.html`
<button onclick=${this.handleClick}>Logs h-welcome</button>
<input oninput=${this.handleInput} />
`;
}
}
HyperWelcome.define('h-welcome'); This is how things work in HyperHTMLElement: you don't need the arrow function at class definition for |
This was me:
So please, next time, maybe read a bit more carefully so none of us would waste any time. Thanks. |
Clearly these discussions are better to be done in Monday and not Friday, my eyes skipped Sorry to have made you waste time, have a good week-end. |
FYI the patch that landed to fix #270 might help your cause too since you are a TypeScript user and turns out TypeScript sucks at transpiling template literals in a standard way. |
Nice, but I have es2015 as target since CE work best with native classes AFAIK. And about the memory leak...well upon further profiling it was due to forgetting to destroy the chart shown within cards 🤦♂️ I was too interested in knowing what happens when nodes are disconnected and I mistakenly immediately thought it was related to hyperHTML. Sorry again for the annoyance 😄 |
What happens when a node is replaced by another one?
Let's take the following example:
What happens with the instance of
<my-comp>
? Is it gargage-collected or is always there in memory ready to come back? The same question arises for the event handler (I'm not usingDOM handleEvent
on purpose because I prefer this way).TLDR; I'm wondering if hyperHTML already cleans up the stuff for me when elements are "unmounted" or better disconnected, or I have to do it myself somehow. Should I add a
disconnectedCallback
in my CE and remove the event listeners?The question arised because I was trying the Performance monitor in Chrome and going back&forward between home and a card in https://ygo.now.sh/ seems to always increase DOM Nodes and event listeners.
The text was updated successfully, but these errors were encountered: