Ionic-framework: bug: Navigating between pages inside an Ionic app is leaking DOM nodes

Created on 31 Aug 2019  路  6Comments  路  Source: ionic-team/ionic-framework

Bug Report

Ionic version:


[x] 4.8.1

Current behavior:

Navigating between pages leaks DOM nodes.

Expected behavior:

Navigating between pages should not leak DOM nodes.

Steps to reproduce:

The easiest way to reproduce it is by repeatedly navigating between two pages while monitoring the DOM nodes count.

Simple demo app which easily reproduces the problem: Ionic navigation DOM node leaks.

Steps to reproduce inside the demo app:

  • open app in Chrome while keeping the devtools Performance monitor open
  • repeatedly perform the following steps:

    1. click the "navigation leak" link

    2. use the browser back button to navigate back to the homepage

    3. optional: press the Collect garbage button in Chrome devtools (found inside the Performance tab)

Notice how each iteration of opening and closing the demo page increases the number of DOM nodes reported by the Performance monitor:

ionic_navigation_dom_leaks

The staircase pattern seems to suggest there's a memory leak that happens while navigating between pages in an Ionic app.

Related code:

Ionic navigation DOM node leaks demo

Other information:

The content of the page linked to seems to affect the number of DOM nodes leaked. For example, if the linked page contains <ion-content>Hello world</ion-content> then the number of leaked DOM nodes after each iteration is 7. However, if the page contains a div instead of an ion-content (e.g.: <div>Hello world</div>) then the number of leaked DOM nodes decreases to 3.

Ionic info:

Ionic:

   Ionic CLI                     : 5.2.7 (/home/vially/.config/yarn/global/node_modules/ionic)
   Ionic Framework               : @ionic/angular 4.8.1
   @angular-devkit/build-angular : 0.801.3
   @angular-devkit/schematics    : 8.1.3
   @angular/cli                  : 8.1.3
   @ionic/angular-toolkit        : 2.0.0

Utility:

   cordova-res : not installed
   native-run  : not installed

System:

   NodeJS : v12.9.1 (/usr/bin/node)
   npm    : 6.11.2
   OS     : Linux 5.2
core bug

Most helpful comment

@liamdebeasi Possibly not the same as the OP's issue. I just remembered this one was still here and seemed on topic.

All 6 comments

it looks like some event listeners are also being leaked:
ionic_navigation_js_listeners_leak

This seems to suggest there are some missing removeEventListener calls.

Confirmed this in my app. Memory references appear to be retained across page refreshes as well. It does appear if you leave the app idling for a while that GC occurs and references are cleaned up, but it does take a while for this to happen.

@liamdebeasi

I believe I have finally traced the memory leak down to the ion-img component. I do not believe it is cleaning up its IntersectionObserver references properly. After hours of pouring over Chrome heap snapshots, this is where I've landed. I'm still tracing down a few other leaks but this one was by far the worst as images often appear in repeated list items / virtual-scroll elements.

Here the observer is created:
https://github.com/ionic-team/ionic/blob/master/core/src/components/img/img.tsx#L46

But there is no "componentDidDestroy" callback to clean up the listener, nor is there any code that would perform such cleanup elsewhere.

I do not know if Stencil supports such a concept, but... without it, (as I understand it) this will never be cleaned up as the Observer will not clean itself up, and the observer contains a reference to the component/element being observed.

I verified this by using the following image component:

<ion-img *ngIf="!native" [src]="_imgUrl" type="image/png"> </ion-img> <img *ngIf="native" [src]="_imgUrl">

When using 'native' images, DOM elements did not leak across page transitions where images were displayed. Garbage collection properly cleans up the Detached Dom elements and the pages can be destroyed.

Using ion-img, dom nodes continued to grow.

Thanks for investigating. Is this the same issue as the one OP posted about? The demo app provided does not seem to make use of ion-img.

@liamdebeasi Possibly not the same as the OP's issue. I just remembered this one was still here and seemed on topic.

Great find @lincolnthree! My demo did not use any ion-img so I would expect there must be some other leaks as well.

However, after using Ionic in a medium sized app for a while now I get the feeling that there are multiple Ionic components that are leaking (or maybe just a few leaks in some heavily used components like the ion-img that you've just identified).

It would be nice if the Ionic team tried to systematically identify and fix all of them at once rather than just try to fix the ones that get reported in various issues (not sure if that's possible though).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

brandyscarney picture brandyscarney  路  3Comments

manucorporat picture manucorporat  路  3Comments

giammaleoni picture giammaleoni  路  3Comments

GeorgeAnanthSoosai picture GeorgeAnanthSoosai  路  3Comments

gio82 picture gio82  路  3Comments