From fed3647a1256e9c99f270671b7af3b675ba21671 Mon Sep 17 00:00:00 2001 From: Michael Dellanoce Date: Thu, 26 Oct 2023 13:17:40 -0400 Subject: [PATCH 1/2] use WeakMap for faster attributeCursor lookup --- .changeset/moody-dots-refuse.md | 5 +++++ packages/rrweb/src/record/mutation.ts | 7 ++++--- 2 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 .changeset/moody-dots-refuse.md diff --git a/.changeset/moody-dots-refuse.md b/.changeset/moody-dots-refuse.md new file mode 100644 index 0000000000..32270da384 --- /dev/null +++ b/.changeset/moody-dots-refuse.md @@ -0,0 +1,5 @@ +--- +'rrweb': patch +--- + +use WeakMap for faster attributeCursor lookup while processing attribute mutations diff --git a/packages/rrweb/src/record/mutation.ts b/packages/rrweb/src/record/mutation.ts index 80943d96ab..440f308696 100644 --- a/packages/rrweb/src/record/mutation.ts +++ b/packages/rrweb/src/record/mutation.ts @@ -142,6 +142,7 @@ export default class MutationBuffer { private texts: textCursor[] = []; private attributes: attributeCursor[] = []; + private attributeMap = new WeakMap(); private removes: removedNodeMutation[] = []; private mapRemoves: Node[] = []; @@ -485,6 +486,7 @@ export default class MutationBuffer { // reset this.texts = []; this.attributes = []; + this.attributeMap = new WeakMap(); this.removes = []; this.addedSet = new Set(); this.movedSet = new Set(); @@ -554,9 +556,7 @@ export default class MutationBuffer { return; } - let item: attributeCursor | undefined = this.attributes.find( - (a) => a.node === m.target, - ); + let item = this.attributeMap.get(m.target); if ( target.tagName === 'IFRAME' && attributeName === 'src' && @@ -578,6 +578,7 @@ export default class MutationBuffer { _unchangedStyles: {}, }; this.attributes.push(item); + this.attributeMap.set(m.target, item); } // Keep this property on inputs that used to be password inputs From 354fbeeb9ea9c753f2283badd8c4f9384d0041d9 Mon Sep 17 00:00:00 2001 From: Michael Dellanoce Date: Thu, 26 Oct 2023 13:47:23 -0400 Subject: [PATCH 2/2] benchmark for attribute mutations --- .../rrweb/test/benchmark/dom-mutation.test.ts | 6 ++++++ .../benchmark-dom-mutation-attributes.html | 21 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 packages/rrweb/test/html/benchmark-dom-mutation-attributes.html diff --git a/packages/rrweb/test/benchmark/dom-mutation.test.ts b/packages/rrweb/test/benchmark/dom-mutation.test.ts index 3da794db45..a4124c3f98 100644 --- a/packages/rrweb/test/benchmark/dom-mutation.test.ts +++ b/packages/rrweb/test/benchmark/dom-mutation.test.ts @@ -42,6 +42,12 @@ const suites: Array< eval: 'window.workload()', times: 5, }, + { + title: 'modify attributes on 10000 DOM nodes', + html: 'benchmark-dom-mutation-attributes.html', + eval: 'window.workload()', + times: 10, + }, ]; function avg(v: number[]): number { diff --git a/packages/rrweb/test/html/benchmark-dom-mutation-attributes.html b/packages/rrweb/test/html/benchmark-dom-mutation-attributes.html new file mode 100644 index 0000000000..3d00b26b4d --- /dev/null +++ b/packages/rrweb/test/html/benchmark-dom-mutation-attributes.html @@ -0,0 +1,21 @@ + + + +