Skip to content

Commit ec27c34

Browse files
committed
ref(replay): Avoid deserializing JSON
1 parent 04edb73 commit ec27c34

File tree

6 files changed

+13
-50
lines changed

6 files changed

+13
-50
lines changed

packages/replay/src/eventBuffer/EventBufferCompressionWorker.ts

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export class EventBufferCompressionWorker extends EventBufferArray {
7272
/**
7373
* Post message to worker and wait for response before resolving promise.
7474
*/
75-
private _postMessage<T>({ id, method, args }: WorkerRequest): Promise<T> {
75+
private _postMessage<T>({ id, method, arg }: WorkerRequest): Promise<T> {
7676
return new Promise((resolve, reject) => {
7777
const listener = ({ data }: MessageEvent): void => {
7878
const response = data as WorkerResponse;
@@ -100,26 +100,18 @@ export class EventBufferCompressionWorker extends EventBufferArray {
100100
resolve(response.response as T);
101101
};
102102

103-
let stringifiedArgs;
104-
try {
105-
stringifiedArgs = JSON.stringify(args);
106-
} catch (err) {
107-
__DEBUG_BUILD__ && logger.error('[Replay] Error when trying to stringify args', err);
108-
stringifiedArgs = '[]';
109-
}
110-
111103
// Note: we can't use `once` option because it's possible it needs to
112104
// listen to multiple messages
113105
this._worker.addEventListener('message', listener);
114-
this._worker.postMessage({ id, method, args: stringifiedArgs });
106+
this._worker.postMessage({ id, method, arg });
115107
});
116108
}
117109

118110
/**
119111
* Finish the request and return the compressed data from the worker.
120112
*/
121113
private async _compressEvents(id: number, events: RecordingEvent[]): Promise<Uint8Array> {
122-
return this._postMessage<Uint8Array>({ id, method: 'compress', args: [events] });
114+
return this._postMessage<Uint8Array>({ id, method: 'compress', arg: JSON.stringify(events) });
123115
}
124116

125117
/** Get the current ID and increment it for the next call. */

packages/replay/src/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export interface SendReplayData {
2424
export interface WorkerRequest {
2525
id: number;
2626
method: string;
27-
args: unknown[];
27+
arg: string;
2828
}
2929

3030
// PerformancePaintTiming and PerformanceNavigationTiming are only available with TS 4.4 and newer

packages/replay/src/worker/worker.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/replay/test/unit/worker/compress.test.ts

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,10 @@ describe('Unit | worker | compress', () => {
1111
},
1212
];
1313

14-
const compressed = compress(events);
14+
const compressed = compress(JSON.stringify(events));
1515

1616
const restored = pako.inflate(compressed, { to: 'string' });
1717

1818
expect(restored).toBe(JSON.stringify(events));
1919
});
20-
21-
it('ignores empty data', () => {
22-
const event = {
23-
id: 1,
24-
foo: ['bar', 'baz'],
25-
};
26-
27-
// @ts-ignore ignoring type for test
28-
const compressed = compress([null, undefined, event]);
29-
30-
const restored = pako.inflate(compressed, { to: 'string' });
31-
32-
expect(restored).toBe(JSON.stringify([event]));
33-
});
3420
});
Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,5 @@
11
import pako from 'pako';
22

3-
type RecordingEvent = Record<string, unknown>;
4-
5-
export function compress(data: RecordingEvent[]): Uint8Array {
6-
return pako.deflate(buildDeflate(data));
7-
}
8-
9-
function buildDeflate(data: RecordingEvent[]): string {
10-
// We cannot use backticks, as that conflicts with the stringified worker
11-
return (
12-
'[' +
13-
data
14-
.filter((event: RecordingEvent) => !!event)
15-
.map(event => JSON.stringify(event))
16-
.join(',') +
17-
']'
18-
);
3+
export function compress(data: string): Uint8Array {
4+
return pako.deflate(data);
195
}

packages/replay/worker/src/handleMessage.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,24 @@
11
import { compress } from './compress';
22

33
interface Handlers {
4-
compress: (data: Record<string, unknown>[]) => void;
4+
compress: (data: string) => void;
55
}
66

77
const handlers: Handlers = {
8-
compress: (data: Record<string, unknown>[]) => {
8+
compress: (data: string) => {
99
return compress(data);
1010
},
1111
};
1212

1313
export function handleMessage(e: MessageEvent): void {
14-
const eventData = e.data as unknown as { method: string; id: number; args: string };
15-
const { method, id, args } = eventData;
16-
const [data] = args ? JSON.parse(args) : [];
14+
const eventData = e.data as unknown as { method: string; id: number; arg: string };
15+
const { method, id, arg } = eventData;
1716

1817
// @ts-ignore this syntax is actually fine
1918
if (method in handlers && typeof handlers[method] === 'function') {
2019
try {
2120
// @ts-ignore this syntax is actually fine
22-
const response = handlers[method](data);
21+
const response = handlers[method](arg);
2322
// @ts-ignore this syntax is actually fine
2423
postMessage({
2524
id,

0 commit comments

Comments
 (0)