Skip to content

Commit

Permalink
fix: start time must be derived from replay (#20839)
Browse files Browse the repository at this point in the history
* fix: start time must be derived from replay

* fix

* Update UI snapshots for `chromium` (2)

---------

Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
pauldambra and github-actions[bot] authored Mar 12, 2024
1 parent bd9c4df commit fb8b5b5
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ export function PlayerInspectorListItem({
title="This event occured before the recording started, likely as the page was loading."
placement="left"
>
<span>{colonDelimitedDuration(item.timeInRecording / 1000, fixedUnits)}</span>
<span className="text-muted">load</span>
</Tooltip>
) : (
colonDelimitedDuration(item.timeInRecording / 1000, fixedUnits)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ export const playerInspectorLogic = kea<playerInspectorLogicType>([
// but we decided to instead store them in the recording data
// we gather more info than rrweb, so we mix the two back together here

return matchNetworkEvents(sessionPlayerData.snapshotsByWindowId)
return filterUnwanted(matchNetworkEvents(sessionPlayerData.snapshotsByWindowId))
},
],

Expand Down Expand Up @@ -915,3 +915,11 @@ export const playerInspectorLogic = kea<playerInspectorLogicType>([
}
}),
])

function filterUnwanted(events: PerformanceEvent[]): PerformanceEvent[] {
// the browser can provide network events that we're not interested in,
// like a navigation to "about:blank"
return events.filter((event) => {
return !(event.entry_type === 'navigation' && event.name && event.name === 'about:blank')
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import { NodeKind } from '~/queries/schema'
import {
AnyPropertyFilter,
EncodedRecordingSnapshot,
PerformanceEvent,
PersonType,
PropertyFilterType,
PropertyOperator,
Expand Down Expand Up @@ -126,28 +125,6 @@ const getHrefFromSnapshot = (snapshot: RecordingSnapshot): string | undefined =>
return (snapshot.data as any)?.href || (snapshot.data as any)?.payload?.href
}

// PerformanceEvent timestamp is for some reason string | number, yuck
function asInt(x: string | number): number {
return typeof x === 'number' ? x : parseInt(x)
}

function getSnapshotSortingTimestamp(e: eventWithTime | undefined): number | undefined {
if (!e) {
return undefined
}
// rrweb network events have a timestamp, but might contain requests from before the recording started
if (e.type === EventType.Plugin && e.data.plugin === 'rrweb/network@1') {
const requests: PerformanceEvent[] = e.data.payload?.['requests'] || []
const sortedRequests = requests.sort(
(a: PerformanceEvent, b: PerformanceEvent) => asInt(a.timestamp) - asInt(b.timestamp)
)
const firstTimestamp = sortedRequests.length ? sortedRequests[0].timestamp : undefined
// if we have no requests, we use the event timestamp
return firstTimestamp !== undefined ? asInt(firstTimestamp) : e.timestamp
}
return e.timestamp
}

export const deduplicateSnapshots = (
newSnapshots?: RecordingSnapshot[],
existingSnapshots?: RecordingSnapshot[]
Expand All @@ -172,7 +149,7 @@ export const deduplicateSnapshots = (
return true
}
})
.sort((a, b) => (getSnapshotSortingTimestamp(a) || 0) - (getSnapshotSortingTimestamp(b) || 0))
.sort((a, b) => a.timestamp - b.timestamp)
}

const generateRecordingReportDurations = (cache: Record<string, any>): RecordingReportLoadTimes => {
Expand Down Expand Up @@ -768,16 +745,9 @@ export const sessionRecordingDataLogic = kea<sessionRecordingDataLogicType>([
],

start: [
(s) => [s.sessionPlayerMetaData, s.sessionPlayerSnapshotData],
(meta, sessionPlayerSnapshotData): Dayjs | undefined => {
// NOTE: We might end up with more snapshots than we knew about when we started the recording so we
// either use the metadata start point or the first snapshot, whichever is earlier.
const start = meta?.start_time ? dayjs(meta.start_time) : undefined
const snapshots = sessionPlayerSnapshotData?.snapshots || []
const firstEventTimestamp = getSnapshotSortingTimestamp(snapshots[0])
return firstEventTimestamp && firstEventTimestamp < (start?.valueOf() ?? 0)
? dayjs(firstEventTimestamp)
: start
(s) => [s.sessionPlayerMetaData],
(meta): Dayjs | undefined => {
return meta?.start_time ? dayjs(meta.start_time) : undefined
},
],

Expand Down

0 comments on commit fb8b5b5

Please sign in to comment.