diff --git a/frontend/__snapshots__/components-networkrequesttiming--basic.png b/frontend/__snapshots__/components-networkrequesttiming--basic.png index ff34c2d27d479..8247b433f71c8 100644 Binary files a/frontend/__snapshots__/components-networkrequesttiming--basic.png and b/frontend/__snapshots__/components-networkrequesttiming--basic.png differ diff --git a/frontend/src/scenes/session-recordings/player/inspector/components/ItemPerformanceEvent.tsx b/frontend/src/scenes/session-recordings/player/inspector/components/ItemPerformanceEvent.tsx index 4dbd3cd4b3f2c..96c4a9e01a143 100644 --- a/frontend/src/scenes/session-recordings/player/inspector/components/ItemPerformanceEvent.tsx +++ b/frontend/src/scenes/session-recordings/player/inspector/components/ItemPerformanceEvent.tsx @@ -317,7 +317,7 @@ export function ItemPerformanceEvent({ ) : ( <> - +

Request started at{' '} @@ -466,29 +466,44 @@ function HeadersDisplay({ ) } -function StatusRow({ status }: { status: number | undefined }): JSX.Element | null { - if (status === undefined) { - return null - } +function StatusRow({ item }: { item: PerformanceEvent }): JSX.Element | null { + let statusRow = null + let methodRow = null + + if (item.response_status) { + const statusDescription = `${item.response_status} ${friendlyHttpStatus[item.response_status] || ''}` - const statusDescription = `${status} ${friendlyHttpStatus[status] || ''}` + let statusType: LemonTagType = 'success' + if (item.response_status >= 400 || item.response_status < 100) { + statusType = 'warning' + } else if (item.response_status >= 500) { + statusType = 'danger' + } - let statusType: LemonTagType = 'success' - if (status >= 400 || status < 100) { - statusType = 'warning' - } else if (status >= 500) { - statusType = 'danger' + statusRow = ( +

+
Status code
+ {statusDescription} +
+ ) } - return ( + if (item.method) { + methodRow = ( +
+
Request method
+
{item.method}
+
+ ) + } + + return methodRow || statusRow ? (

-
- Status code - {statusDescription} -
+ {methodRow} + {statusRow}

- ) + ) : null } diff --git a/frontend/src/scenes/session-recordings/player/inspector/components/Timing/NetworkRequestTiming.tsx b/frontend/src/scenes/session-recordings/player/inspector/components/Timing/NetworkRequestTiming.tsx index df65c02326529..f77aeadf524dd 100644 --- a/frontend/src/scenes/session-recordings/player/inspector/components/Timing/NetworkRequestTiming.tsx +++ b/frontend/src/scenes/session-recordings/player/inspector/components/Timing/NetworkRequestTiming.tsx @@ -8,35 +8,6 @@ import { LemonDivider } from 'lib/lemon-ui/LemonDivider' import { SimpleKeyValueList } from 'scenes/session-recordings/player/inspector/components/SimpleKeyValueList' import { LemonButton } from 'lib/lemon-ui/LemonButton' -function colorForEntry(entryType: string | undefined): string { - switch (entryType) { - case 'domComplete': - return getSeriesColor(1) - case 'domInteractive': - return getSeriesColor(2) - case 'pageLoaded': - return getSeriesColor(3) - case 'first-contentful-paint': - return getSeriesColor(4) - case 'css': - return getSeriesColor(6) - case 'xmlhttprequest': - return getSeriesColor(7) - case 'fetch': - return getSeriesColor(8) - case 'other': - return getSeriesColor(9) - case 'script': - return getSeriesColor(10) - case 'link': - return getSeriesColor(11) - case 'first-paint': - return getSeriesColor(11) - default: - return getSeriesColor(13) - } -} - export interface EventPerformanceMeasure { start: number end: number @@ -50,7 +21,8 @@ const perfSections = [ 'dns lookup', 'connection time', 'tls time', - 'waiting for first byte (TTFB)', + 'request queuing time', + 'waiting for first byte', 'receiving response', 'document processing', ] as const @@ -62,7 +34,9 @@ const perfDescriptions: Record<(typeof perfSections)[number], string> = { 'dns lookup': 'The time taken to complete any DNS lookup for the resource.', 'connection time': 'The time taken to establish a connection to the server to retrieve the resource.', 'tls time': 'The time taken for the SSL/TLS handshake.', - 'waiting for first byte (TTFB)': 'The time taken waiting for the server to start returning a response.', + 'request queuing time': "The time taken waiting in the browser's task queue once ready to make a request.", + 'waiting for first byte': + 'The time taken waiting for the server to start returning a response. Also known as TTFB or time to first byte.', 'receiving response': 'The time taken to receive the response from the server.', 'document processing': 'The time taken to process the document after the response from the server has been received.', @@ -71,29 +45,36 @@ const perfDescriptions: Record<(typeof perfSections)[number], string> = { function colorForSection(section: (typeof perfSections)[number]): string { switch (section) { case 'redirect': - return getSeriesColor(1) - case 'app cache': return getSeriesColor(2) - case 'dns lookup': + case 'app cache': return getSeriesColor(3) - case 'connection time': + case 'dns lookup': return getSeriesColor(4) + case 'connection time': + return getSeriesColor(5) case 'tls time': return getSeriesColor(6) - case 'waiting for first byte (TTFB)': + case 'request queuing time': return getSeriesColor(7) - case 'receiving response': + case 'waiting for first byte': return getSeriesColor(8) - case 'document processing': + case 'receiving response': return getSeriesColor(9) - default: + case 'document processing': return getSeriesColor(10) + default: + return getSeriesColor(11) } } /** * There are defined sections to performance measurement. We may have data for some or all of them * + * + * 0) Queueing + * - from start_time + * - until the first item with activity + * * 1) Redirect * - from startTime which would also be redirectStart * - until redirect_end @@ -127,9 +108,6 @@ function colorForSection(section: (typeof perfSections)[number]): string { * - until load_event_end * * see https://nicj.net/resourcetiming-in-practice/ - * - * @param perfEntry - * @param maxTime */ function calculatePerformanceParts(perfEntry: PerformanceEvent): Record { const performanceParts: Record = {} @@ -138,7 +116,7 @@ function calculatePerformanceParts(perfEntry: PerformanceEvent): Record 1) { // find in eventsMapping[capturedRequest.url][capturedRequest.startTime] by matching capturedRequest.endTime and element.response_end const matchedEndTime = matchedStartTime.find( @@ -135,6 +136,7 @@ export function matchNetworkEvents(snapshotsByWindowId: Record request_body?: Body response_body?: Body + method?: string } export interface CurrentBillCycleType {