memory leak with angular animation
See original GitHub issueπ bug report
Description
When using *ngIf to hide element which contains another element with angular animation trigger, appearing DOM nodes that garbage cleaner can`t remove. I inspect amount of DOM nodes by chrome performance monitor. In small app it`s doesn't matter but in app with a lot of components and animations it`s appear to be critical, especially on mobile㪠Minimal Reproduction
Create div which shown on *ngIf; inside it create another div with animation trigger like this: [@trigger]; try to hide and show parent div, while watching performance monitor; you notice that amount of DOM nodes increasing and this nodes can`t be cleaned by garbage collectorhttps://stackblitz.com/edit/angular-tguytc
π Your Environment
Angular Version:
Angular CLI: 7.3.9
Node: 10.15.3
OS: win32 x64
Angular: 7.2.15
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router
Package Version
-----------------------------------------------------------
@angular-devkit/architect 0.13.9
@angular-devkit/build-angular 0.13.9
@angular-devkit/build-optimizer 0.13.9
@angular-devkit/build-webpack 0.13.9
@angular-devkit/core 7.3.9
@angular-devkit/schematics 7.3.9
@angular/cli 7.3.9
@ngtools/webpack 7.3.9
@schematics/angular 7.3.9
@schematics/update 0.13.9
rxjs 6.3.3
typescript 3.2.4
webpack 4.29.0
UPD: One of possible solutions: you can separate child element with animation trigger in new component, so ngDestroy of new component works fine and clear element when needed
Issue Analytics
- State:
- Created 4 years ago
- Reactions:15
- Comments:15 (3 by maintainers)
Top Results From Across the Web
Angular Memory Leaks: how to create & fix them - Medium
We'll create an Angular app with memory leaks then with chrome DevTools ... before and after Memory Leak Fix (animation created by Rakia...
Read more >Angular Animation causing DOM Leak - Stack Overflow
I am using Angular animations for the first time and am currently running into an memory leak. After removing the animations from theΒ ......
Read more >How to Detect and Fix Memory Leaks With Chrome DevTools
I'll create a web app suffering from memory leak and will fix it with chrome DevTools. This post is useful for Angular, React,...
Read more >Angular Observable Memory leak - StackBlitz
A angular-cli project based on @angular/animations, @angular/compiler, @angular/core, @angular/common, @angular/platform-browser-dynamic, @angular/forms,Β ...
Read more >Memory Leak In Angular - Observable - Sipios
Here is the memory leak: when we click on the button for the first time, we create a child component that manages the...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
This issue is driving me crazy for a couple of days now. I have analyzed this behavior a lot and I found out that it isnβt only a problem with *ngIf but also with *ngFor (where I faced this issue too) and I guess that it is also a problem with *ngSwitchCase (not tested). I think in general you can say: If you have a parent element which has child elements inside it with animation triggers and the parent element gets removed (e. g. by *ngFor or *ngIf) before the child elements get removed, the child elements with animation triggers attached are causing a DOM leak (in case of *ngFor with a huge list - a massive one).
I guess it doesnβt even matter if the parent element itself has an animation trigger attached to it.
For example (the scenario where I faced this issue):
I have a multidimensional array, where each entry of the array is another array. Like:
In my template I use a nested *ngFor to visualize this. Each array is a own div and inside that div each entry of the array is a paragraph. The paragraphs have animation triggers attached to them to animate them at application runtime.
For example:
Now, when you do arr.length = 0 to clear the array, all parapgraphs are leaked as Detached DOM elements. If you remove the animation trigger and do the same, that doesnβt happen.
This also doesnβt happen with an one dimensional array and a single *ngFor.
A workaround that I found out:
First clear all array entries inside the main array, then run change detection and let angular destroy all elements from the inner *ngFor (the paragraphs), then clear the main array and run change detection again so angular can now destroy all elements from the outer *ngFor (the divs). If you do it like that, everything gets cleaned up as expected.
But this workaround feels really hacky so I donβt think that it is a good option.
I also had a similar issue with *ngIf, where the parent container with the *ngIf attached had a child element with an animation trigger. This also caused a memory leak (of the whole component template). There I used the same workaround as above: First removed the child element itself with an *ngIf, then run change detection and let angular update the template, and then remove the parent container with the original *ngIf. This also fixed the issue.
But as I said, this workaround isnβt a solution because it is really dirty and feels hacky. So I hope this will get fixed soon, because it makes the @angular/animations package almost unusable for large applications with much animations.
also ran into thisβ¦ especially annoying in our case because that loop with the animation is run through on a timer (itβs kind of a slideshow situation) which also is endlessβ¦ which means this is guaranteed to crash the browser-tab given enough time π§¨