With introduction of fat arrow functions β the implicit bind magic, JS developers found an everlasting π towards them.
Although they were eye pleasing and a delight, they bought with a variety of concerns if not implemented wisely.
One such case i found myself having numerous conversations with my peers about; is having anonymous functions to handle the events which developers find easy to use and miss the subtle ugly memory leak they cause.
P.S This article won't be dwelling to the π depths of memory leak identification and resolutions but to emphasis on the fact that taking the easy route in this case will end up hitting the hardest.
β¨ Theory
An anonymous function might not be cleared by GC (garbage collection) efficiently during a mark and sweep phase as the references to it cannot be determined hence GC fails to recover back the allocated memory
β¨ Lab setup
- Production react build running on chrome
- Run about 10k state changes on each scenario of with and without anonymous implementation to trigger re-renders
β¨ Analysis
That being said, let's jump on to the crux and look at some stats;
Recording a snapshot of each implementation clearly depicts a memory leak with the anonymous function implementation
Snapshot without anonymous functions
πΈ fig (i)
Snapshot with anonymous functions
πΈ fig (ii)
As we compare fig (i) with fig (ii) it's clear that the memory allocation has been freed up by GC in fig (i) as opposed to that of fig(ii)
The exaggerated example intends to portrays the memory leak with the approach; which holds true for apps of multiple complexities in the real world
β¨ Conclusion =>
Anonymous fat arrow functions within render methods pave way for a memory leak and ipso facto an anti-pattern
β¨ Show me the code
Jeevan-Kishore / space-complexity
A project to demonstrate space complexity over time
If you have questions, let us know in the comments and we are looking forward for your feedback π»
Top comments (6)
I like to write anonymous event handlers on occasion and my work app is all Inversion of Control - so we have a master event bus etc. We just use hooks to add the events and then it's fine as it is properly removed.
We mostly use our master event bus which has a special hook, but the generic one looks like this:
Used like this:
Why aren't anonymous event handlers destroyed when the view is destroyed? Sounds like a design point issue.
It would be fair to say if the event emitter is destroyed then they are unreachable and are released. If you attach to a global event handler or something that will survive a while, they aren't removed because nothing calls
removeListener
. It would be true of a non-anonymous listener true I guess.I'm guessing people aren't working out how to remember the anonymous function to then call removeListener. It's one of those, the sugar is so sweet someone didn't notice the sudden weight gain ;)
The responsibility is likely delegated to the user to remove listeners when they feel it's time to do so.
I agree with @miketalbot on how people overlook it.
How is this issue different for anonymous functions declared using the
function
keyword?@savagepixie It isn't different, as long as there are creation of objects which cannot be GC'd the issue remains the same. The article addresses the latter as people prefer to use the fat arrows widely because of binding