From a1ec9a273e6634eec67098fdd880ee681648fbbd Mon Sep 17 00:00:00 2001 From: fukang wang Date: Mon, 22 May 2023 10:19:28 +0800 Subject: [PATCH] perf: optimize performance of the DoubleLinkedList get (#1220) * perf: optimize performance of the DoubleLinkedList get * fix: delete addedNodeIndexArr --- .changeset/gold-terms-look.md | 5 +++ packages/rrweb/src/record/mutation.ts | 14 ++++++- .../rrweb/test/benchmark/dom-mutation.test.ts | 6 +++ .../benchmark-dom-mutation-add-and-move.html | 37 +++++++++++++++++++ 4 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 .changeset/gold-terms-look.md create mode 100644 packages/rrweb/test/html/benchmark-dom-mutation-add-and-move.html diff --git a/.changeset/gold-terms-look.md b/.changeset/gold-terms-look.md new file mode 100644 index 0000000000..4ad333341c --- /dev/null +++ b/.changeset/gold-terms-look.md @@ -0,0 +1,5 @@ +--- +'rrweb': patch +--- + +perf: optimize performance of the DoubleLinkedList get diff --git a/packages/rrweb/src/record/mutation.ts b/packages/rrweb/src/record/mutation.ts index e0b03eb1dd..337394acf1 100644 --- a/packages/rrweb/src/record/mutation.ts +++ b/packages/rrweb/src/record/mutation.ts @@ -48,6 +48,7 @@ function isNodeInLinkedList(n: Node | NodeInLinkedList): n is NodeInLinkedList { class DoubleLinkedList { public length = 0; public head: DoubleLinkedListNode | null = null; + public tail: DoubleLinkedListNode | null = null; public get(position: number) { if (position >= this.length) { @@ -95,6 +96,9 @@ class DoubleLinkedList { node.next = this.head; this.head = node; } + if (node.next === null) { + this.tail = node; + } this.length++; } @@ -108,11 +112,15 @@ class DoubleLinkedList { this.head = current.next; if (this.head) { this.head.previous = null; + } else { + this.tail = null; } } else { current.previous.next = current.next; if (current.next) { current.next.previous = current.previous; + } else { + this.tail = current.previous; } } if (n.__ln) { @@ -368,8 +376,10 @@ export default class MutationBuffer { } } if (!node) { - for (let index = addList.length - 1; index >= 0; index--) { - const _node = addList.get(index); + let tailNode = addList.tail; + while (tailNode) { + const _node = tailNode; + tailNode = tailNode.previous; // ensure _node is defined before attempting to find value if (_node) { const parentId = this.mirror.getId(_node.value.parentNode); diff --git a/packages/rrweb/test/benchmark/dom-mutation.test.ts b/packages/rrweb/test/benchmark/dom-mutation.test.ts index 57050fb400..3da794db45 100644 --- a/packages/rrweb/test/benchmark/dom-mutation.test.ts +++ b/packages/rrweb/test/benchmark/dom-mutation.test.ts @@ -36,6 +36,12 @@ const suites: Array< eval: 'window.workload()', times: 5, }, + { + title: 'create 10000 DOM nodes and move it to new container', + html: 'benchmark-dom-mutation-add-and-move.html', + eval: 'window.workload()', + times: 5, + }, ]; function avg(v: number[]): number { diff --git a/packages/rrweb/test/html/benchmark-dom-mutation-add-and-move.html b/packages/rrweb/test/html/benchmark-dom-mutation-add-and-move.html new file mode 100644 index 0000000000..922b8c9ffc --- /dev/null +++ b/packages/rrweb/test/html/benchmark-dom-mutation-add-and-move.html @@ -0,0 +1,37 @@ + + +
+ + +