Hammerjs events are causing memory leaks (detached nodes)
See original GitHub issueI’m submitting a…
[ ] Regression (a behavior that used to work and stopped working in a new release)
[X] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
Current behavior
When angular removes the event listener for a hammer event, it only calls the .off()
function of the hammer manager instance.
addEventListener(element: HTMLElement, eventName: string, handler: Function): Function { const zone = this.manager.getZone(); eventName = eventName.toLowerCase();
return zone.runOutsideAngular(() => {
// Creating the manager bind events, must be done outside of angular
const mc = this._config.buildHammer(element);
const callback = function(eventObj: HammerInput) {
zone.runGuarded(function() { handler(eventObj); });
};
mc.on(eventName, callback);
return () => mc.off(eventName, callback); <----- right here
});
}
However, this is not destroying the manager instance, which is holding a reference to the element. This is causing detached nodes for every element that has a @HostListener
listening for a hammer touch event.
Expected behavior
When removing an event listener for a hammer touch event, no detached nodes should be left over.
Therefore, in addition to .off()
Angular should also call destroy()
.
Minimal reproduction of the problem with instructions
Here is a simple demo reproducing the problem. https://stackblitz.com/edit/angular-j95qco
- Repeatedly clicking the ‘toggle button’ button will add and remove a
my-button
component with anHostListener
on a tab event. - After that, go to the Memory tab in Chrome Dev Tools and create a heap snapshot.
- Filter the list for detached.
- You will see a bunch of detached nodes. Expand the nodes to see that
my-button
is causing it.
I also added a quick fix. Go to gesture.service.ts and un-comment the code between line 31 and 39. The fix simply calls .destroy()
ind addition to .off()
What is the motivation / use case for changing the behavior?
The current behavior drastically decreases performance of apps with lot of touch events.
Environment
Angular version: 5.0.0
Browser:
- [X] Chrome (desktop) version 63
Issue Analytics
- State:
- Created 6 years ago
- Reactions:6
- Comments:5 (1 by maintainers)
Looking for this fix too, is it still not merged??
What’s the status about the PR? Is there a reason it is not getting merged?