Skip to content

Commit 37d084e

Browse files
committed
fix: memory leak mutation buffer on stop/start record (#1707)
1 parent 1760cf8 commit 37d084e

File tree

3 files changed

+19
-7
lines changed

3 files changed

+19
-7
lines changed

packages/rrweb/src/record/mutation.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,10 @@ export default class MutationBuffer {
526526
this.mutationCb(payload);
527527
};
528528

529+
public destroy() {
530+
this.serializeAbortController.abort();
531+
}
532+
529533
private genTextAreaValueMutation = (textarea: HTMLTextAreaElement) => {
530534
let item = this.attributeMap.get(textarea);
531535
if (!item) {

packages/rrweb/src/record/observer.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ function getEventTarget(event: Event | NonStandardEvent): EventTarget | null {
8181
export function initMutationObserver(
8282
options: MutationBufferParam,
8383
rootEl: Node,
84-
): MutationObserver {
84+
): listenerHandler {
8585
const mutationBuffer = new MutationBuffer();
8686
mutationBuffers.push(mutationBuffer);
8787
// see mutation.ts for details
@@ -99,7 +99,15 @@ export function initMutationObserver(
9999
childList: true,
100100
subtree: true,
101101
});
102-
return observer;
102+
103+
return () => {
104+
observer.disconnect();
105+
mutationBuffer.destroy();
106+
const idx = mutationBuffers.indexOf(mutationBuffer);
107+
if (idx > -1) {
108+
mutationBuffers.splice(idx, 1);
109+
}
110+
}
103111
}
104112

105113
function initMoveObserver({
@@ -1306,9 +1314,9 @@ export function initObservers(
13061314
}
13071315

13081316
mergeHooks(o, hooks);
1309-
let mutationObserver: MutationObserver | undefined;
1317+
let removeMutationObserver: listenerHandler | undefined;
13101318
if (o.recordDOM) {
1311-
mutationObserver = initMutationObserver(o, o.doc);
1319+
removeMutationObserver = initMutationObserver(o, o.doc);
13121320
}
13131321
const mousemoveHandler = initMoveObserver(o);
13141322
const mouseInteractionHandler = initMouseInteractionObserver(o);
@@ -1350,7 +1358,7 @@ export function initObservers(
13501358

13511359
return callbackWrapper(() => {
13521360
mutationBuffers.forEach((b) => b.reset());
1353-
mutationObserver?.disconnect();
1361+
removeMutationObserver?.();
13541362
mousemoveHandler();
13551363
mouseInteractionHandler();
13561364
scrollHandler();

packages/rrweb/src/record/shadow-dom-manager.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export class ShadowDomManager {
5353
if (!isNativeShadowDom(shadowRoot)) return;
5454
if (this.shadowDoms.has(shadowRoot)) return;
5555
this.shadowDoms.add(shadowRoot);
56-
const observer = initMutationObserver(
56+
const removeObserver = initMutationObserver(
5757
{
5858
...this.bypassOptions,
5959
doc,
@@ -63,7 +63,7 @@ export class ShadowDomManager {
6363
},
6464
shadowRoot,
6565
);
66-
this.restoreHandlers.push(() => observer.disconnect());
66+
this.restoreHandlers.push(() => removeObserver());
6767
this.restoreHandlers.push(
6868
initScrollObserver({
6969
...this.bypassOptions,

0 commit comments

Comments
 (0)