question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

No way to clean up resources from component recycler?

See original GitHub issue

The 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.

screenshot 2017-12-17 13 21 15 screenshot 2017-12-17 13 21 39

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.

screenshot 2017-12-17 13 35 04

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:closed
  • Created 6 years ago
  • Reactions:6
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

8reactions
developitcommented, Dec 19, 2017

You can effectively disable recycling like so:

class MyHeavyComponent extends Component {
  destroy = () => {
    this.nextBase = null;
  };
  componentWillUnmount() {
    setTimeout(this.destroy);
  }
}

If you want to automatically disable recycling for all components, perhaps something like this:

let bases = new WeakMap();
Object.defineProperty(Component.prototype, 'nextBase', {
  get() { return bases.get(this); },
  set(base) { bases.set(this, base); }
});

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.

3reactions
marvinhagemeistercommented, Mar 4, 2019

We just merged the code for our next version of Preact into master. The recycler is no more 🎉

Read more comments on GitHub >

github_iconTop Results From Across the Web

5 Ways to Make Your Cleanup More Sustainable
No matter how you give back and clean up, these tips will help you be even more sustainable in your efforts. 1. Collect...
Read more >
Managing and Reducing Wastes: A Guide for Commercial ...
Focus first on waste prevention, which will help eliminate waste at the source, saving natural resources and energy and cutting costs. Evaluate recycling...
Read more >
What is the best way to clean up an Object in Java?
Generally you only would clean up non-object resources like open streams. finalize() is not guaranteed to be called because the garbage collector is...
Read more >
Waste Management and Recycling - The Ocean Cleanup
“There is no such thing as waste – only wasted resources. When you can create value from waste, it isn't waste anymore.
Read more >
Exploring the three Rs of waste… | Rogue Disposal & Recycling
There are all sorts of ways you can reuse items to help reduce your trash footprint: Clean out your closet. Maybe your size...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found