commit b7a31d0c386f7164a14147801a97d46c3db4d3b4
parent fb30f0ce1099a61a4d4109551459feab8912934d
Author: Alexandre Poirot <poirot.alex@gmail.com>
Date: Mon, 13 Oct 2025 08:21:53 +0000
Bug 1993262 - [devtools] Fix inspector reflows and toolbar panel leaks. r=devtools-reviewers,nchevobbe
These reflows leak is a regular leak where a DOM listener is not correctly removed.
The toolbar one is slightly special as we really leaking, but accumulating
bound function on top of previously bound function, leading to a chain of bound functions.
I imagine it may ultimately become a performance issue.
Differential Revision: https://phabricator.services.mozilla.com/D267974
Diffstat:
2 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/devtools/client/inspector/inspector.js b/devtools/client/inspector/inspector.js
@@ -159,6 +159,9 @@ class Inspector extends EventEmitter {
this.onSidebarSelect = this.onSidebarSelect.bind(this);
this.onSidebarShown = this.onSidebarShown.bind(this);
this.onSidebarToggle = this.onSidebarToggle.bind(this);
+ this.addNode = this.addNode.bind(this);
+ this.onEyeDropperDone = this.onEyeDropperDone.bind(this);
+ this.onEyeDropperButtonClicked = this.onEyeDropperButtonClicked.bind(this);
this.prefObserver = new PrefObserver("devtools.");
this.prefObserver.on(
@@ -1496,7 +1499,6 @@ class Inspector extends EventEmitter {
this.#teardownToolbar();
// Setup the add-node button.
- this.addNode = this.addNode.bind(this);
this.addNodeButton = this.panelDoc.getElementById(
"inspector-element-add-button"
);
@@ -1512,9 +1514,6 @@ class Inspector extends EventEmitter {
}
if (canShowEyeDropper) {
- this.onEyeDropperDone = this.onEyeDropperDone.bind(this);
- this.onEyeDropperButtonClicked =
- this.onEyeDropperButtonClicked.bind(this);
this.eyeDropperButton = this.panelDoc.getElementById(
"inspector-eyedropper-toggle"
);
diff --git a/devtools/server/actors/reflow.js b/devtools/server/actors/reflow.js
@@ -479,14 +479,17 @@ class WindowResizeObserver extends Observable {
}
_startListeners() {
- this.listenerTarget.addEventListener("resize", this.onResize);
+ this._abortController = new AbortController();
+ this.listenerTarget.addEventListener("resize", this.onResize, {
+ signal: this._abortController.signal,
+ });
}
_stopListeners() {
- if (!this.listenerTarget) {
- return;
+ if (this._abortController) {
+ this._abortController.abort();
+ this._abortController = null;
}
- this.listenerTarget.removeEventListener("resize", this.onResize);
}
onNavigate() {
@@ -504,6 +507,7 @@ class WindowResizeObserver extends Observable {
if (this.targetActor) {
this.targetActor.off("navigate", this.onNavigate);
}
+ this._stopListeners();
super.destroy();
}