Skip to content

Commit 3b45d3c

Browse files
billyvgcmanallen
authored andcommitted
feat(replay): Only use replayerStepper when finished fetching replay data (#79565)
Previously, a new ReplayReader instance would be created after every page of recording segments finishes. This meant that replays with hundreds of segments, a new `ReplayReader` would be constructed `<# of segments> / 100` times (corresponds to the number of recording segments pages requests from the API). With the DOM nodes chart, this was made 2x as bad (but that is gone now)! We now pass the "fetching" state from `useReplayData` into `ReplayReader` and do not initialize `replayerStepper` until fetching is completed so that it is only called once. This should fix #77809
1 parent 9808784 commit 3b45d3c

File tree

10 files changed

+39
-2
lines changed

10 files changed

+39
-2
lines changed

static/app/components/events/eventReplay/index.spec.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ const mockReplay = ReplayReader.factory({
6464
},
6565
}),
6666
errors: mockErrors,
67+
fetching: false,
6768
attachments: RRWebInitFrameEventsFixture({
6869
timestamp: new Date('Sep 22, 2022 4:58:39 PM UTC'),
6970
}),

static/app/components/events/eventReplay/replayClipPreview.spec.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ const mockReplay = ReplayReader.factory({
3838
duration: duration(10, 'seconds'),
3939
}),
4040
errors: [],
41+
fetching: false,
4142
attachments: RRWebInitFrameEventsFixture({
4243
timestamp: new Date('Sep 22, 2022 4:58:39 PM UTC'),
4344
}),

static/app/components/events/eventReplay/replayPreview.spec.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const mockReplay = ReplayReader.factory({
4343
},
4444
}),
4545
errors: [],
46+
fetching: false,
4647
attachments: RRWebInitFrameEventsFixture({
4748
timestamp: new Date('Sep 22, 2022 4:58:39 PM UTC'),
4849
}),

static/app/utils/replays/getDiffTimestamps.spec.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ function getMockReplay(rrwebEvents: any[], errors: ReplayError[]) {
6767
const replay = ReplayReader.factory({
6868
replayRecord,
6969
errors,
70+
fetching: false,
7071
attachments,
7172
});
7273

@@ -97,6 +98,7 @@ function getMockReplayWithCrumbFrame(
9798
const replay = ReplayReader.factory({
9899
replayRecord,
99100
errors,
101+
fetching: false,
100102
attachments,
101103
});
102104

static/app/utils/replays/hooks/useReplayReader.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export default function useReplayReader({
2828
}: Props): ReplayReaderResult {
2929
const replayId = parseReplayId(replaySlug);
3030

31-
const {attachments, errors, replayRecord, ...replayData} = useReplayData({
31+
const {attachments, errors, replayRecord, fetching, ...replayData} = useReplayData({
3232
orgSlug,
3333
replayId,
3434
});
@@ -63,15 +63,17 @@ export default function useReplayReader({
6363
clipWindow: memoizedClipWindow,
6464
errors,
6565
featureFlags,
66+
fetching,
6667
replayRecord,
6768
}),
68-
[attachments, memoizedClipWindow, errors, featureFlags, replayRecord]
69+
[attachments, memoizedClipWindow, errors, featureFlags, fetching, replayRecord]
6970
);
7071

7172
return {
7273
...replayData,
7374
attachments,
7475
errors,
76+
fetching,
7577
replay,
7678
replayId,
7779
replayRecord,

static/app/utils/replays/playback/providers/replayPlayerEventsContext.spec.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ describe('replayPlayerEventsContext', () => {
2424
const mockReplay = ReplayReader.factory({
2525
attachments: [],
2626
errors: [],
27+
fetching: false,
2728
replayRecord: ReplayRecordFixture(),
2829
});
2930

@@ -42,6 +43,7 @@ describe('replayPlayerEventsContext', () => {
4243
const mockReplay = ReplayReader.factory({
4344
attachments: [],
4445
errors: [],
46+
fetching: false,
4547
replayRecord: ReplayRecordFixture(),
4648
});
4749
const mockRRwebFrames: any[] = [];

static/app/utils/replays/replayReader.spec.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,23 @@ describe('ReplayReader', () => {
3232
const missingAttachments = ReplayReader.factory({
3333
attachments: undefined,
3434
errors: [],
35+
fetching: false,
3536
replayRecord,
3637
});
3738
expect(missingAttachments).toBeNull();
3839

3940
const missingErrors = ReplayReader.factory({
4041
attachments: [],
4142
errors: undefined,
43+
fetching: false,
4244
replayRecord,
4345
});
4446
expect(missingErrors).toBeNull();
4547

4648
const missingRecord = ReplayReader.factory({
4749
attachments: [],
4850
errors: [],
51+
fetching: false,
4952
replayRecord: undefined,
5053
});
5154
expect(missingRecord).toBeNull();
@@ -61,6 +64,7 @@ describe('ReplayReader', () => {
6164
ReplayConsoleEventFixture({timestamp: minuteTen}),
6265
],
6366
errors: [],
67+
fetching: false,
6468
replayRecord: ReplayRecordFixture({
6569
started_at: new Date('2023-12-25T00:01:00'),
6670
finished_at: new Date('2023-12-25T00:09:00'),
@@ -79,6 +83,7 @@ describe('ReplayReader', () => {
7983
const replay = ReplayReader.factory({
8084
attachments: [],
8185
errors: [],
86+
fetching: false,
8287
replayRecord,
8388
});
8489

@@ -211,6 +216,7 @@ describe('ReplayReader', () => {
211216
const replay = ReplayReader.factory({
212217
attachments,
213218
errors: [],
219+
fetching: false,
214220
replayRecord,
215221
});
216222

@@ -231,6 +237,7 @@ describe('ReplayReader', () => {
231237
}),
232238
],
233239
errors: [],
240+
fetching: false,
234241
replayRecord,
235242
});
236243

@@ -253,6 +260,7 @@ describe('ReplayReader', () => {
253260
}),
254261
],
255262
errors: [],
263+
fetching: false,
256264
replayRecord,
257265
});
258266

@@ -292,6 +300,7 @@ describe('ReplayReader', () => {
292300
}),
293301
],
294302
errors: [],
303+
fetching: false,
295304
replayRecord,
296305
});
297306

@@ -320,6 +329,7 @@ describe('ReplayReader', () => {
320329
const replay = ReplayReader.factory({
321330
attachments,
322331
errors: [],
332+
fetching: false,
323333
replayRecord,
324334
});
325335

@@ -352,6 +362,7 @@ describe('ReplayReader', () => {
352362
const replay = ReplayReader.factory({
353363
attachments: [snapshot, increment],
354364
errors: [],
365+
fetching: false,
355366
replayRecord,
356367
});
357368

@@ -426,6 +437,7 @@ describe('ReplayReader', () => {
426437
breadcrumbAttachment3,
427438
],
428439
errors: [error1, error2, error3],
440+
fetching: false,
429441
replayRecord: ReplayRecordFixture({
430442
started_at: replayStartedAt,
431443
finished_at: replayFinishedAt,

static/app/utils/replays/replayReader.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ interface ReplayReaderParams {
6565
*/
6666
errors: ReplayError[] | undefined;
6767

68+
/**
69+
* Is replay data still fetching?
70+
*/
71+
fetching: boolean;
72+
6873
/**
6974
* The root Replay event, created at the start of the browser session.
7075
*/
@@ -168,6 +173,7 @@ export default class ReplayReader {
168173
replayRecord,
169174
clipWindow,
170175
featureFlags,
176+
fetching,
171177
}: ReplayReaderParams) {
172178
if (!attachments || !replayRecord || !errors) {
173179
return null;
@@ -179,6 +185,7 @@ export default class ReplayReader {
179185
errors,
180186
replayRecord,
181187
featureFlags,
188+
fetching,
182189
clipWindow,
183190
});
184191
} catch (err) {
@@ -192,6 +199,7 @@ export default class ReplayReader {
192199
attachments: [],
193200
errors: [],
194201
featureFlags,
202+
fetching,
195203
replayRecord,
196204
clipWindow,
197205
});
@@ -202,10 +210,12 @@ export default class ReplayReader {
202210
attachments,
203211
errors,
204212
featureFlags,
213+
fetching,
205214
replayRecord,
206215
clipWindow,
207216
}: RequiredNotNull<ReplayReaderParams>) {
208217
this._cacheKey = domId('replayReader-');
218+
this._fetching = fetching;
209219

210220
if (replayRecord.is_archived) {
211221
this._replayRecord = replayRecord;
@@ -305,6 +315,7 @@ export default class ReplayReader {
305315
private _duration: Duration = duration(0);
306316
private _errors: ErrorFrame[] = [];
307317
private _featureFlags: string[] | undefined = [];
318+
private _fetching: boolean = true;
308319
private _optionFrame: undefined | OptionFrame;
309320
private _replayRecord: ReplayRecord;
310321
private _sortedBreadcrumbFrames: BreadcrumbFrame[] = [];
@@ -437,6 +448,9 @@ export default class ReplayReader {
437448
};
438449

439450
getExtractDomNodes = memoize(async () => {
451+
if (this._fetching) {
452+
return null;
453+
}
440454
const {onVisitFrame, shouldVisitFrame} = extractDomNodes;
441455

442456
const results = await replayerStepper({

static/app/views/issueDetails/groupReplays/groupReplays.spec.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ const mockReplay = ReplayReader.factory({
6363
duration: duration(10, 'seconds'),
6464
}),
6565
errors: [],
66+
fetching: false,
6667
attachments: RRWebInitFrameEventsFixture({
6768
timestamp: new Date('Sep 22, 2022 4:58:39 PM UTC'),
6869
}),

static/app/views/replays/detail/tagPanel/index.spec.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const mockReplay = ReplayReader.factory({
1818
},
1919
}),
2020
errors: [],
21+
fetching: false,
2122
attachments: [],
2223
});
2324

0 commit comments

Comments
 (0)