From 9c6edfe2261680b4e92284be69f9d183b1eca8f4 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Fri, 3 Nov 2023 12:09:21 +0100 Subject: [PATCH] ref: Avoid unnecessary cloning of objects or arrays (#1340) --- .changeset/gold-apples-joke.md | 5 ++++ packages/rrweb/src/record/observer.ts | 28 +++++-------------- .../rrweb/src/record/observers/canvas/2d.ts | 2 +- .../record/observers/canvas/serialize-args.ts | 2 +- .../src/record/observers/canvas/webgl.ts | 2 +- 5 files changed, 15 insertions(+), 24 deletions(-) create mode 100644 .changeset/gold-apples-joke.md diff --git a/.changeset/gold-apples-joke.md b/.changeset/gold-apples-joke.md new file mode 100644 index 0000000000..4ad27974b8 --- /dev/null +++ b/.changeset/gold-apples-joke.md @@ -0,0 +1,5 @@ +--- +'rrweb': patch +--- + +ref: Avoid unnecessary cloning of objects or arrays diff --git a/packages/rrweb/src/record/observer.ts b/packages/rrweb/src/record/observer.ts index e23e5a1004..a8dde3319f 100644 --- a/packages/rrweb/src/record/observer.ts +++ b/packages/rrweb/src/record/observer.ts @@ -405,15 +405,6 @@ function initViewportResizeObserver( return on('resize', updateDimension, win); } -function wrapEventWithUserTriggeredFlag( - v: inputValue, - enable: boolean, -): inputValue { - const value = { ...v }; - if (!enable) delete value.userTriggered; - return value; -} - export const INPUT_TAGS = ['INPUT', 'TEXTAREA', 'SELECT']; const lastInputValueMap: WeakMap = new WeakMap(); function initInputObserver({ @@ -477,10 +468,9 @@ function initInputObserver({ } cbWithDedup( target, - callbackWrapper(wrapEventWithUserTriggeredFlag)( - { text, isChecked, userTriggered }, - userTriggeredOnInput, - ), + userTriggeredOnInput + ? { text, isChecked, userTriggered } + : { text, isChecked }, ); // if a radio was checked // the other radios with the same name attribute will be unchecked. @@ -490,16 +480,12 @@ function initInputObserver({ .querySelectorAll(`input[type="radio"][name="${name}"]`) .forEach((el) => { if (el !== target) { + const text = (el as HTMLInputElement).value; cbWithDedup( el, - callbackWrapper(wrapEventWithUserTriggeredFlag)( - { - text: (el as HTMLInputElement).value, - isChecked: !isChecked, - userTriggered: false, - }, - userTriggeredOnInput, - ), + userTriggeredOnInput + ? { text, isChecked: !isChecked, userTriggered: false } + : { text, isChecked: !isChecked }, ); } }); diff --git a/packages/rrweb/src/record/observers/canvas/2d.ts b/packages/rrweb/src/record/observers/canvas/2d.ts index d74a4edc0c..b496b6b93a 100644 --- a/packages/rrweb/src/record/observers/canvas/2d.ts +++ b/packages/rrweb/src/record/observers/canvas/2d.ts @@ -45,7 +45,7 @@ export default function initCanvas2DMutationObserver( // Using setTimeout as toDataURL can be heavy // and we'd rather not block the main thread setTimeout(() => { - const recordArgs = serializeArgs([...args], win, this); + const recordArgs = serializeArgs(args, win, this); cb(this.canvas, { type: CanvasContext['2D'], property: prop, diff --git a/packages/rrweb/src/record/observers/canvas/serialize-args.ts b/packages/rrweb/src/record/observers/canvas/serialize-args.ts index adc15a91b9..30e20fcb0c 100644 --- a/packages/rrweb/src/record/observers/canvas/serialize-args.ts +++ b/packages/rrweb/src/record/observers/canvas/serialize-args.ts @@ -133,7 +133,7 @@ export const serializeArgs = ( win: IWindow, ctx: RenderingContext, ) => { - return [...args].map((arg) => serializeArg(arg, win, ctx)); + return args.map((arg) => serializeArg(arg, win, ctx)); }; export const isInstanceOfWebGLObject = ( diff --git a/packages/rrweb/src/record/observers/canvas/webgl.ts b/packages/rrweb/src/record/observers/canvas/webgl.ts index 6a4fe6c849..680890f666 100644 --- a/packages/rrweb/src/record/observers/canvas/webgl.ts +++ b/packages/rrweb/src/record/observers/canvas/webgl.ts @@ -53,7 +53,7 @@ function patchGLPrototype( 'tagName' in this.canvas && !isBlocked(this.canvas, blockClass, blockSelector, true) ) { - const recordArgs = serializeArgs([...args], win, this); + const recordArgs = serializeArgs(args, win, this); const mutation: canvasMutationWithType = { type, property: prop,