diff --git a/.changeset/shaggy-bags-sneeze.md b/.changeset/shaggy-bags-sneeze.md new file mode 100644 index 0000000000..9eec928219 --- /dev/null +++ b/.changeset/shaggy-bags-sneeze.md @@ -0,0 +1,5 @@ +--- +"rrweb": patch +--- + +optimize attribute serialization diff --git a/packages/rrweb/src/record/mutation.ts b/packages/rrweb/src/record/mutation.ts index 3feae589f6..dc1a1e9f88 100644 --- a/packages/rrweb/src/record/mutation.ts +++ b/packages/rrweb/src/record/mutation.ts @@ -19,6 +19,7 @@ import type { removedNodeMutation, addedNodeMutation, Optional, + mutationCallbackParam, } from '@rrweb/types'; import { isBlocked, @@ -260,6 +261,32 @@ export default class MutationBuffer { this.emit(); // clears buffer if not locked/frozen }; + private serializeTexts( + input: textCursor[], + addedIds: Set, + ): mutationCallbackParam['texts'] { + const texts = []; + for (let i = 0; i < input.length; i++) { + const n = input[i].node; + const parent = dom.parentNode(n); + if (parent && (parent as Element).tagName === 'TEXTAREA') { + // the node is being ignored as it isn't in the mirror, so shift mutation to attributes on parent textarea + this.genTextAreaValueMutation(parent as HTMLTextAreaElement); + } + + const id = this.mirror.getId(n); + if (addedIds.has(id) || !this.mirror.has(id)) { + continue; + } + texts.push({ + id, + value: input[i].value, + }); + } + + return texts; + } + public emit = () => { if (this.frozen || this.locked) { return; @@ -448,23 +475,7 @@ export default class MutationBuffer { } const payload = { - texts: this.texts - .map((text) => { - const n = text.node; - const parent = dom.parentNode(n); - if (parent && (parent as Element).tagName === 'TEXTAREA') { - // the node is being ignored as it isn't in the mirror, so shift mutation to attributes on parent textarea - this.genTextAreaValueMutation(parent as HTMLTextAreaElement); - } - return { - id: this.mirror.getId(n), - value: text.value, - }; - }) - // no need to include them on added elements, as they have just been serialized with up to date attribubtes - .filter((text) => !addedIds.has(text.id)) - // text mutation's id was not in the mirror map means the target node has been removed - .filter((text) => this.mirror.has(text.id)), + texts: this.serializeTexts(this.texts, addedIds), attributes: this.attributes .map((attribute) => { const { attributes } = attribute;