diff --git a/.changeset/mean-tips-impress.md b/.changeset/mean-tips-impress.md new file mode 100644 index 00000000..b6b00221 --- /dev/null +++ b/.changeset/mean-tips-impress.md @@ -0,0 +1,5 @@ +--- +'rrweb': patch +--- + +perf: optimize the performance of record in processMutation phase diff --git a/packages/rrweb/src/record/mutation.ts b/packages/rrweb/src/record/mutation.ts index 2e5132c9..e0b03eb1 100644 --- a/packages/rrweb/src/record/mutation.ts +++ b/packages/rrweb/src/record/mutation.ts @@ -656,6 +656,9 @@ export default class MutationBuffer { // this node was already recorded in other buffer, ignore it if (this.processedNodeManager.inOtherBuffer(n, this)) return; + // if n is added to set, there is no need to travel it and its' children again + if (this.addedSet.has(n) || this.movedSet.has(n)) return; + if (this.mirror.hasNode(n)) { if (isIgnored(n, this.mirror)) { return; diff --git a/packages/rrweb/test/benchmark/dom-mutation.test.ts b/packages/rrweb/test/benchmark/dom-mutation.test.ts index 47fbfe5e..57050fb4 100644 --- a/packages/rrweb/test/benchmark/dom-mutation.test.ts +++ b/packages/rrweb/test/benchmark/dom-mutation.test.ts @@ -30,6 +30,12 @@ const suites: Array< eval: 'window.workload()', times: 10, }, + { + title: 'create 1000 DOM nodes and append into its previous looped node', + html: 'benchmark-dom-mutation-multiple-descendant-add.html', + eval: 'window.workload()', + times: 5, + }, ]; function avg(v: number[]): number { diff --git a/packages/rrweb/test/html/benchmark-dom-mutation-multiple-descendant-add.html b/packages/rrweb/test/html/benchmark-dom-mutation-multiple-descendant-add.html new file mode 100644 index 00000000..3e727cae --- /dev/null +++ b/packages/rrweb/test/html/benchmark-dom-mutation-multiple-descendant-add.html @@ -0,0 +1,18 @@ + + + +