Skip to content

Commit c85b2e4

Browse files
authored
feat(replay): Change to use preset quality values (#9903)
Instead of using canvas recording quality values direct to rrweb, use presets to control image quality and fps. Closes getsentry/team-replay#325
1 parent ce9efc7 commit c85b2e4

File tree

4 files changed

+68
-12
lines changed

4 files changed

+68
-12
lines changed

packages/replay/src/constants.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,33 @@ export const MAX_REPLAY_DURATION = 3_600_000; // 60 minutes in ms;
5353

5454
/** Default attributes to be ignored when `maskAllText` is enabled */
5555
export const DEFAULT_IGNORED_ATTRIBUTES = ['title', 'placeholder'];
56+
57+
export const CANVAS_QUALITY = {
58+
low: {
59+
sampling: {
60+
canvas: 1,
61+
},
62+
dataURLOptions: {
63+
type: 'image/webp',
64+
quality: 0.25,
65+
},
66+
},
67+
medium: {
68+
sampling: {
69+
canvas: 2,
70+
},
71+
dataURLOptions: {
72+
type: 'image/webp',
73+
quality: 0.4,
74+
},
75+
},
76+
high: {
77+
sampling: {
78+
canvas: 4,
79+
},
80+
dataURLOptions: {
81+
type: 'image/webp',
82+
quality: 0.5,
83+
},
84+
},
85+
};

packages/replay/src/replay.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { logger } from '@sentry/utils';
66

77
import {
88
BUFFER_CHECKOUT_TIME,
9+
CANVAS_QUALITY,
910
SESSION_IDLE_EXPIRE_DURATION,
1011
SESSION_IDLE_PAUSE_DURATION,
1112
SLOW_CLICK_SCROLL_TIMEOUT,
@@ -340,15 +341,12 @@ export class ReplayContainer implements ReplayContainerInterface {
340341
...(this.recordingMode === 'buffer' && { checkoutEveryNms: BUFFER_CHECKOUT_TIME }),
341342
emit: getHandleRecordingEmit(this),
342343
onMutation: this._onMutationHandler,
343-
...(canvas && {
344-
recordCanvas: true,
345-
sampling: { canvas: canvas.fps || 4 },
346-
dataURLOptions: {
347-
type: canvas.type || 'image/webp',
348-
quality: canvas.quality || 0.6,
349-
},
350-
getCanvasManager: canvas.manager,
351-
}),
344+
...(canvas &&
345+
canvas.manager && {
346+
recordCanvas: true,
347+
getCanvasManager: canvas.manager,
348+
...(CANVAS_QUALITY[canvas.quality || 'medium'] || CANVAS_QUALITY.medium),
349+
}),
352350
});
353351
} catch (err) {
354352
this._handleException(err);

packages/replay/src/types/replay.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -233,9 +233,7 @@ export interface ReplayPluginOptions extends ReplayNetworkOptions {
233233
captureExceptions: boolean;
234234
traceInternals: boolean;
235235
canvas: {
236-
fps?: number;
237-
quality?: number;
238-
type?: string;
236+
quality?: 'low' | 'medium' | 'high';
239237
manager: (options: GetCanvasManagerOptions) => CanvasManagerInterface;
240238
};
241239
}>;

packages/replay/test/integration/rrweb.test.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { CanvasManagerInterface } from '../../src/types';
12
import { resetSdkMock } from '../mocks/resetSdkMock';
23
import { useFakeTimers } from '../utils/use-fake-timers';
34

@@ -40,4 +41,33 @@ describe('Integration | rrweb', () => {
4041
}
4142
`);
4243
});
44+
45+
it('calls rrweb.record with default canvas options', async () => {
46+
const { mockRecord } = await resetSdkMock({
47+
replayOptions: {
48+
_experiments: {
49+
canvas: {
50+
// @ts-expect-error This should return
51+
// CanvasManagerInterface, but we don't care about it
52+
// for this test
53+
manager: () => null,
54+
},
55+
},
56+
},
57+
});
58+
59+
expect(mockRecord).toHaveBeenLastCalledWith(
60+
expect.objectContaining({
61+
recordCanvas: true,
62+
getCanvasManager: expect.any(Function),
63+
dataURLOptions: {
64+
quality: 0.4,
65+
type: 'image/webp',
66+
},
67+
sampling: {
68+
canvas: 2,
69+
},
70+
}),
71+
);
72+
});
4373
});

0 commit comments

Comments
 (0)