diff --git a/frontend/src/scenes/session-recordings/player/controller/Seekbar.tsx b/frontend/src/scenes/session-recordings/player/controller/Seekbar.tsx index 4274979dcfe65..8f4053244b24a 100644 --- a/frontend/src/scenes/session-recordings/player/controller/Seekbar.tsx +++ b/frontend/src/scenes/session-recordings/player/controller/Seekbar.tsx @@ -3,6 +3,7 @@ import './Seekbar.scss' import clsx from 'clsx' import { useActions, useValues } from 'kea' import { useEffect, useRef } from 'react' +import React from 'react' import { RecordingSegment } from '~/types' @@ -14,6 +15,45 @@ import { PlayerSeekbarPreview } from './PlayerSeekbarPreview' import { PlayerSeekbarTicks } from './PlayerSeekbarTicks' import { seekbarLogic } from './seekbarLogic' +// the seekbar and its children can be accidentally re-rendered as the player ticks +const SeekbarSegment = React.memo(function SeekbarSegmentRaw({ + segment, + durationMs, +}: { + segment: RecordingSegment + durationMs: number +}): JSX.Element { + return ( +
+ ) +}) + +function SeekbarSegments(): JSX.Element { + const { logicProps } = useValues(sessionRecordingPlayerLogic) + const { segments, durationMs } = useValues(sessionRecordingDataLogic(logicProps)) + return ( +
+ {segments?.map((segment: RecordingSegment) => ( + + ))} +
+ ) +} + export function Seekbar(): JSX.Element { const { sessionRecordingId, logicProps } = useValues(sessionRecordingPlayerLogic) const { seekToTime } = useActions(sessionRecordingPlayerLogic) @@ -48,22 +88,7 @@ export function Seekbar(): JSX.Element { onMouseDown={handleDown} onTouchStart={handleDown} > -
- {sessionPlayerData.segments?.map((segment: RecordingSegment) => ( -
- ))} -
+
([ thumbLeftPos: [ -THUMB_OFFSET, { - setThumbLeftPos: (_, { thumbLeftPos }) => thumbLeftPos, + setThumbLeftPos: (_, { thumbLeftPos }) => { + // we receive this number to many decimal places, so we round it to 1 decimal place + // since otherwise we render dependent components + // thousands of times more than we need to + return parseFloat(thumbLeftPos.toFixed(1)) + }, }, ], cursorDiff: [ @@ -82,7 +87,12 @@ export const seekbarLogic = kea([ (selectors) => [selectors.sessionPlayerData], (sessionPlayerData) => { if (sessionPlayerData?.bufferedToTime && sessionPlayerData?.segments && sessionPlayerData?.durationMs) { - return 100 * (sessionPlayerData?.bufferedToTime / sessionPlayerData.durationMs) + // we calculate this number to many decimal places, so we round it to 1 decimal place + // since otherwise we render dependent components + // thousands of times more than we need to + return parseFloat( + (100 * (sessionPlayerData?.bufferedToTime / sessionPlayerData.durationMs)).toFixed(1) + ) } return 0 },