First I want to mention that this issue is related to 1.x version of iron-validatable-behavior used with version 1.x of iron-meta.
Also, this issue occurs only when using Polymer.Settings.lazyRegister = true.
Description
iron-validatable-behavior keeps a reference to a single instance of iron-meta to store the validators.
This singleton instance is created in the registered callback:
registered: function() {
Polymer.IronValidatableBehaviorMeta = new Polymer.IronMeta({type: 'validator'});
}
When using lazyRegister = true, the created iron-meta will have dataHost set to the parent Polymer element containing the validatable.
(When not using lazyRegister, there is no dataHost available during the registered callback)
If this element is removed from the dom, the IronMeta singleton instance will hold a reference to a detached dom tree via the dataHost property.
(In our application, we load/unload routes elements dynamically, so this can be a quite big detached dom tree).
A side issue is that Polymer.IronValidatableBehaviorMeta is not really a singleton, as it is re-created each time an element using iron-validatable-behavior is registered.
Steps to reproduce the issue
I was not able to create a Jsbin to reproduce this issue, as I've not managed to create a jsbin with version 1.x of polymer elements.
But I created a simple test case that you can drop in the test folder of the component repository (see attached file).
-
checkout branch 1.x and run bower install
-
Copy attached leak.txt file to the test folder of the repository and rename it to leak.html
-
run polymer serve
-
open http://127.0.0.1:8081/components/iron-validatable-behavior/test/leak.html
-
Take a heap snapshot in Chrome DevTools
-
click on the Add/remove <leak-element> from dom button to add the an element with an approx 4MB text property
-
Take a heap snapshot
-
click on the Add/remove <leak-element> from dom button to remove the element
-
Take a heap snapshot
Heap size should be (almost) the same between 1st and last snapshot.
You can verify the expected behavior by reproducing the steps above but clicking on the Add/remove <noleak-element> from dom, which does not contain an iron-validatable element. Heap size should not change between first and last snapshot.
iron-meta 2.0 seems to have solved this, with a new constructor for this element that will not set any reference to a dom tree.
As our application is quite big and we cannot upgrade soon, would it still be possible to fix this issue ?
I could make a PR with the following fix:
registered: function() {
if (!Polymer.IronValidatableBehaviorMeta) {
Polymer.IronValidatableBehaviorMeta = new Polymer.IronMeta({type: 'validator'});
Polymer.IronValidatableBehaviorMeta.dataHost = null;
}
},
leak.txt
First I want to mention that this issue is related to 1.x version of
iron-validatable-behaviorused with version 1.x ofiron-meta.Also, this issue occurs only when using
Polymer.Settings.lazyRegister = true.Description
iron-validatable-behaviorkeeps a reference to a single instance ofiron-metato store the validators.This singleton instance is created in the
registeredcallback:When using
lazyRegister = true, the creatediron-metawill havedataHostset to the parent Polymer element containing the validatable.(When not using lazyRegister, there is no dataHost available during the
registeredcallback)If this element is removed from the dom, the IronMeta singleton instance will hold a reference to a detached dom tree via the
dataHostproperty.(In our application, we load/unload routes elements dynamically, so this can be a quite big detached dom tree).
A side issue is that
Polymer.IronValidatableBehaviorMetais not really a singleton, as it is re-created each time an element usingiron-validatable-behavioris registered.Steps to reproduce the issue
I was not able to create a Jsbin to reproduce this issue, as I've not managed to create a jsbin with version 1.x of polymer elements.
But I created a simple test case that you can drop in the test folder of the component repository (see attached file).
checkout branch 1.x and run bower install
Copy attached leak.txt file to the test folder of the repository and rename it to leak.html
run polymer serve
open http://127.0.0.1:8081/components/iron-validatable-behavior/test/leak.html
Take a heap snapshot in Chrome DevTools
click on the
Add/remove <leak-element> from dombutton to add the an element with an approx 4MB text propertyTake a heap snapshot
click on the
Add/remove <leak-element> from dombutton to remove the elementTake a heap snapshot
Heap size should be (almost) the same between 1st and last snapshot.
You can verify the expected behavior by reproducing the steps above but clicking on the
Add/remove <noleak-element> from dom, which does not contain an iron-validatable element. Heap size should not change between first and last snapshot.iron-meta2.0 seems to have solved this, with a new constructor for this element that will not set any reference to a dom tree.As our application is quite big and we cannot upgrade soon, would it still be possible to fix this issue ?
I could make a PR with the following fix:
leak.txt