From 48310f8356fe8ae292c6f6b00faa71881beeb51c Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Tue, 19 Dec 2023 13:31:13 +0100 Subject: [PATCH 1/2] ref: Avoid async --- .../record/observers/canvas/canvas-manager.ts | 82 ++++++++++--------- 1 file changed, 43 insertions(+), 39 deletions(-) diff --git a/packages/rrweb/src/record/observers/canvas/canvas-manager.ts b/packages/rrweb/src/record/observers/canvas/canvas-manager.ts index e23f62979a..b7e5780510 100644 --- a/packages/rrweb/src/record/observers/canvas/canvas-manager.ts +++ b/packages/rrweb/src/record/observers/canvas/canvas-manager.ts @@ -232,46 +232,50 @@ export class CanvasManager implements CanvasManagerInterface { } lastSnapshotTime = timestamp; - getCanvas() - // eslint-disable-next-line @typescript-eslint/no-misused-promises - .forEach(async (canvas: HTMLCanvasElement) => { - const id = this.mirror.getId(canvas); - if (snapshotInProgressMap.get(id)) return; - snapshotInProgressMap.set(id, true); - if (['webgl', 'webgl2'].includes((canvas as ICanvas).__context)) { - // if the canvas hasn't been modified recently, - // its contents won't be in memory and `createImageBitmap` - // will return a transparent imageBitmap - - const context = canvas.getContext((canvas as ICanvas).__context) as - | WebGLRenderingContext - | WebGL2RenderingContext - | null; - if ( - context?.getContextAttributes()?.preserveDrawingBuffer === false - ) { - // Hack to load canvas back into memory so `createImageBitmap` can grab it's contents. - // Context: https://twitter.com/Juice10/status/1499775271758704643 - // Preferably we set `preserveDrawingBuffer` to true, but that's not always possible, - // especially when canvas is loaded before rrweb. - // This hack can wipe the background color of the canvas in the (unlikely) event that - // the canvas background was changed but clear was not called directly afterwards. - // Example of this hack having negative side effect: https://visgl.github.io/react-map-gl/examples/layers - context.clear(context.COLOR_BUFFER_BIT); - } + getCanvas().forEach((canvas: HTMLCanvasElement) => { + const id = this.mirror.getId(canvas); + if (snapshotInProgressMap.get(id)) return; + snapshotInProgressMap.set(id, true); + if (['webgl', 'webgl2'].includes((canvas as ICanvas).__context)) { + // if the canvas hasn't been modified recently, + // its contents won't be in memory and `createImageBitmap` + // will return a transparent imageBitmap + + const context = canvas.getContext((canvas as ICanvas).__context) as + | WebGLRenderingContext + | WebGL2RenderingContext + | null; + if ( + context?.getContextAttributes()?.preserveDrawingBuffer === false + ) { + // Hack to load canvas back into memory so `createImageBitmap` can grab it's contents. + // Context: https://twitter.com/Juice10/status/1499775271758704643 + // Preferably we set `preserveDrawingBuffer` to true, but that's not always possible, + // especially when canvas is loaded before rrweb. + // This hack can wipe the background color of the canvas in the (unlikely) event that + // the canvas background was changed but clear was not called directly afterwards. + // Example of this hack having negative side effect: https://visgl.github.io/react-map-gl/examples/layers + context.clear(context.COLOR_BUFFER_BIT); } - const bitmap = await createImageBitmap(canvas); - worker.postMessage( - { - id, - bitmap, - width: canvas.width, - height: canvas.height, - dataURLOptions: options.dataURLOptions, - }, - [bitmap], - ); - }); + } + + createImageBitmap(canvas) + .then((bitmap) => { + worker.postMessage( + { + id, + bitmap, + width: canvas.width, + height: canvas.height, + dataURLOptions: options.dataURLOptions, + }, + [bitmap], + ); + }) + .catch(() => { + // noop + }); + }); rafId = requestAnimationFrame(takeCanvasSnapshots); }; From 0ee739786992b74630b1848b5ac3f6df1a937a76 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Wed, 20 Dec 2023 09:11:50 +0100 Subject: [PATCH 2/2] re-throw in callback wrapper --- .../rrweb/src/record/observers/canvas/canvas-manager.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/rrweb/src/record/observers/canvas/canvas-manager.ts b/packages/rrweb/src/record/observers/canvas/canvas-manager.ts index b7e5780510..f3290edcfe 100644 --- a/packages/rrweb/src/record/observers/canvas/canvas-manager.ts +++ b/packages/rrweb/src/record/observers/canvas/canvas-manager.ts @@ -272,8 +272,10 @@ export class CanvasManager implements CanvasManagerInterface { [bitmap], ); }) - .catch(() => { - // noop + .catch((error) => { + callbackWrapper(() => { + throw error; + })(); }); }); rafId = requestAnimationFrame(takeCanvasSnapshots);