No way to clean up resources from component recycler?
See original GitHub issueThe component recycler is a great idea for performance. However, its current implementation creates a situation where it is not possible–as far as I can tell–to ever clean up resources that are reclaimed but never reused.
Take a look at this jsfiddle to see what I mean:
https://jsfiddle.net/n5ngymr7/8/
If you open Google Chrome’s Memory tab and snoop around, you’ll see that CustomComponent and its orphaned HTML DOM nodes are hanging around in memory after I’ve caused them to unmount.
I think this is by design, the idea being that those components may eventually get reused, and at that point, it’ll render faster. However, this approach is not desirable in the situation where those components are never (or infrequently) reused. Think of a single page app that moves to a rare view that uses 10,000 instances of a heavy custom component. The user navigates away from that page, and that memory is never reclaimed, making it effectively a memory leak. Any other javascript outside of preact that requires lots of memory will just have less to work with.
The situation is made worse by passing closures into props. Because the closure must hold onto references–and the reference to props is maintained by the component recycler–those references also hang around forever.
In my specific case, I’m working with video embeds. When a customer calls video.remove()
, they expect it to clean up after itself. We cannot accomplish that right now because of these recycled references in preact.
I was thinking that the right solution to this might be to create a legitimate top-level destroy(parent, merge)
function. Functionally, it would perform a render() like in my jsfiddle, but also pass another argument that tells it not to collect components. I’d be interested in submitting a PR for that if you think it’s the right approach. If not, I’m interested in hearing what else could work! Or if I’m totally wrong, that would be good to know, too. 😄
Thanks for listening.
Issue Analytics
- State:
- Created 6 years ago
- Reactions:6
- Comments:7 (3 by maintainers)
Top GitHub Comments
You can effectively disable recycling like so:
If you want to automatically disable recycling for all components, perhaps something like this:
As for changes to Preact itself, recycling needs to be removed entirely. We did this for elements earlier in the year and changed the diff to account for it, we just need to do the same for components. I’m working on something to this effect right now and will be publishing my findings shortly.
We just merged the code for our next version of Preact into
master
. The recycler is no more 🎉