-
Notifications
You must be signed in to change notification settings - Fork 437
Open
Description
This is related to the memory leak work fixed as part of #592.
That issue fixed cleaning up eventListeners when the controller is removed/replaced within the page. However, there are cases where the element with an action can be updated within the controller (such as an input or button changing in response to other actions in a form).
I've altered the example from that issue to reproduce the new issue:
<html>
<head>
<title>EventListenerMaps memory leak</title>
<script type="module">
import { Application, Controller } from "https://unpkg.com/@hotwired/stimulus/dist/stimulus.js"
window.Stimulus = Application.start()
Stimulus.register("boosts", class extends Controller {
doClick() { process(500) }
})
</script>
<script>
function process(count) {
let i = 0
let handler = setInterval(function () {
if (++i > count) {
clearInterval(handler)
} else {
element = document.getElementById("replace-in-controller")
element.replaceWith(element.cloneNode(true))
}
}, 1)
}
</script>
</head>
<body>
<div data-controller="boosts">
<div id="replace-in-controller">
To reproduce:
<ul>
<li>Check heap snapshot</li>
<li>Click "trigger leak" button</li>
<li>Check heap snapshot again</li>
</ul>
<button data-action="click->boosts#doClick">trigger leak</button>
</div>
</div>
</body>
</html>
Comparing the heap before and after clicking this button, you can see the detached elements relating to event listeners:
In this case it appears that we execute
stimulus/src/core/binding_observer.ts
Line 70 in c953af5
| this.delegate.bindingDisconnected(binding) |
clearEventListeners so they are not removed.Metadata
Metadata
Assignees
Labels
No labels