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.

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 collector

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

github_iconTop GitHub Comments

8reactions
Sazeidyacommented, Jun 14, 2019

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:

let arr = [
    ["test01", "test02", "test03"],
    ["test11", "test12", "test13"],
    ["test21", "test22", "test23"],
    ["test31", "test32", "test33"],
]

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:

<div *ngFor="let list of arr"">
    <p [@exampleAnimation]="exampleState *ngFor="let entry of list>{{entry}}</p>
</div

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.

3reactions
NoUsernamecommented, Apr 23, 2021

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 🧨

Read more comments on GitHub >

github_iconTop 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 >

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