Search code examples
angularmemory-leaksangular-materialgoogle-chrome-devtoolsmaterial-components-web

Angular Material not releasing DOM nodes/Js event listeners


When I visit the Material Components Demo page and switch between the pages (e.g. Autocomplete and Badge), I can see in the Chrome dev-tools Performance monitor, that the number of DOM nodes and JS event listeners constantly increases.

Example:

  • I open Overview (in an incognito window, so that there are no other chrome-extensions active)
    • on the Memory tab start a garbage collection (GC)
    • DOM Nodes ~1800 / JS Event listeners ~400
  • now click on Badge in the left-hand side-menu & start GC
    • DOM Nodes ~2400/ JS Event listeners ~500
  • Back to Overview & start GC
    • DOM Nodes ~3500/ JS Event listeners ~700

Note: also memory increases when we visit multiple pages and then start a GC

enter image description here

Shouldn't a garbage collection free the dom-nodes of the previous page?
Or is this a memory leak in the Material Components library (or maybe in the demo app)?

I ask because we also see this in our production app (which is large) and there it seems to have a severe performance impact.


Solution

  • Shouldn't a garbage collection free the dom-nodes of the previous page?

    Yes. The garbage collector will free all DOM-nodes, that are not referenced anymore.
    So in a well-behaved application/library switching from one route to another should not leak any memory and the Performance monitor tab should show the exact same numbers as before.

    BUT: there may be good reasons in some cases to keep references to DOM nodes, e.g. maybe the library uses some sort of cache

    Or is this a memory leak in the Material Components library (or maybe in the demo app)?

    Also yes. It seems that the Material Components library has memory leak issues: Here are some open issues:

    Also the Angular Ivy renderer causes memory-leaks:

    Stackblitz hint:
    I was not able to reproduce some issues on Stackblitz (i.e. I saw the memory leaks locally, but the same code on Stackblitz worked). The reason was, that Ivy was deactivated on Stackblitz (but my local ng-cli had Ivy activated by default). We can activate Ivy in the Stackblitz settings:
    enter image description here

    Chrome-Dev-Tools hint:
    Before starting a garbage collection we should:

    • remove all breakpoints
    • clear the console (the messages may contain references which will keep them from being garbage collected.
    • avoid chrome extension: use an incognito window or even better a new empty chrome-profile