polymer: dom-if memory leak
Description
dom-if with restamp causes memory to be leaked until the window is refreshed. This does not work well with SPAs.
Expected outcome
Memory to be cleaned up when the garbage collector runs after a page has been left.
Actual outcome
Memory is leaked until the page is refreshed
Steps to reproduce
Use the polymer-2 starter kit. Modify my-app.html by replacing the normal view code in iron-pages with
<template is="dom-if" if="[[isView1]]" restamp>
<my-view1 name="view1"></my-view1>
</template>
<template is="dom-if" if="[[isView2]]" restamp>
<my-view2 name="view2"></my-view2>
</template>
<template is="dom-if" if="[[isView3]]" restamp>
<my-view3 name="view3"></my-view3>
</template>
Inside of _routePageChanged(page): add this code after this.page = page || 'view';
if (page === 'view1') {
this.isView1 = true;
this.isView2 = false;
this.isView3 = false;
} else if (page === 'view2') {
this.isView1 = false;
this.isView2 = true;
this.isView3 = false;
} else if (page === 'view3') {
this.isView1 = false;
this.isView2 = false;
this.isView3 = true;
}
Adding this code to my-view2.html makes it easy to see the memory leak.
connectedCallback() {
super.connectedCallback();
this.hugeArray = [];
for (var i = 0; i < 1000 * 100; i++) {
this.hugeArray.push(Math.ceil(Math.random() * 100))
}
}
This was taken after switching between the views and forcing a garbage collect after landing back on view1.

Browsers Affected
- Chrome
- Edge
- Firefox
- IE 11
- Safari 8
- Safari 9
Versions
- Polymer: v2.6, v3.0.2
- webcomponents: v1.2
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 19 (4 by maintainers)
Commits related to this issue
- Use set and clear debouncer upon completion. Fixes #5250. — committed to Polymer/polymer by kevinpschaaf 5 years ago
- Use set and clear debouncer upon completion. Fixes #5250 — committed to Polymer/polymer by kevinpschaaf 5 years ago
- Revert "Use set and clear debouncer upon completion. Fixes #5250" This reverts commit e8d2314476a3ddcd804ca5afe5881f6f717736d2. — committed to Polymer/polymer by kevinpschaaf 5 years ago
- Use set and clear debouncer upon completion. Fixes #5250 — committed to Polymer/polymer by kevinpschaaf 5 years ago
- Merge pull request #5499 from Polymer/5250-fix-memleak [3.x] Use set and clear debouncer upon completion. Fixes #5250. — committed to Polymer/polymer by kevinpschaaf 5 years ago
- Merge pull request #5500 from Polymer/5250-fix-memleak-2.x [2.x] Use set and clear debouncer upon completion. Fixes #5250 — committed to Polymer/polymer by kevinpschaaf 5 years ago
I found this issue on Polymer 2 and it still exists on Polymer 3. Both
dom-ifanddom-repeatare registered their function to global debouncer.Items in this global debouncer list cannot be removed. It causes memory leak for any elements that use this elements in their template. We need to manually execute the following statement to prevent this memory leak.
I added
Polymer.flush()to_routePageChanged(page)inmy-app.htmlin the polymer 2 starter kit. This is my result from the same tests as before.While it seems like with this change, it is no longer leaking memory, it is still leaking nodes.
@nazarsa For Polymer 2, the fix for this is in 2.7.1.
I’ve found out:
in flush.html enqueueDebouncer is called from dom-if, but flush or flushDebouncers is never called.
see: