import {Fragment, useMemo} from 'react'; import styled from '@emotion/styled'; import EmptyMessage from 'sentry/components/emptyMessage'; import Placeholder from 'sentry/components/placeholder'; import {useReplayContext} from 'sentry/components/replays/replayContext'; import {t} from 'sentry/locale'; import {space} from 'sentry/styles/space'; import {useQuery} from 'sentry/utils/queryClient'; import countDomNodes from 'sentry/utils/replays/countDomNodes'; import type ReplayReader from 'sentry/utils/replays/replayReader'; import DomNodesChart from 'sentry/views/replays/detail/memoryPanel/domNodesChart'; import MemoryChart from 'sentry/views/replays/detail/memoryPanel/memoryChart'; function useCountDomNodes({replay}: {replay: null | ReplayReader}) { return useQuery( ['countDomNodes', replay], () => countDomNodes({ frames: replay?.getRRWebMutations(), rrwebEvents: replay?.getRRWebFrames(), startTimestampMs: replay?.getStartTimestampMs() ?? 0, }), {enabled: Boolean(replay), cacheTime: Infinity} ); } export default function MemoryPanel() { const { currentTime, currentHoverTime, isFetching, replay, setCurrentHoverTime, setCurrentTime, } = useReplayContext(); const memoryFrames = replay?.getMemoryFrames(); const {data: frameToCount} = useCountDomNodes({replay}); const domNodeData = useMemo( () => Array.from(frameToCount?.values() || []), [frameToCount] ); const memoryChart = !replay || isFetching ? ( ) : !replay || !memoryFrames?.length ? ( ) : ( {t('Heap Size')} ); const domNodesChart = !replay || isFetching ? ( ) : ( {t('DOM Nodes')} ); return ( {memoryChart} {domNodesChart} ); } const Grid = styled('div')` display: grid; grid-template-rows: 1fr 1fr; grid-template-columns: 1fr; gap: ${space(1)}; justify-content: center; height: 100%; `; const ChartWrapper = styled('div')` border: 1px solid ${p => p.theme.border}; border-radius: ${space(0.5)}; padding: ${space(1)}; overflow: hidden; display: flex; flex-direction: column; & > * { flex-grow: 1; } `; const ChartTitle = styled('h5')` font-size: ${p => p.theme.fontSizeLarge}; font-weight: ${p => p.theme.text.cardTitle.fontWeight}; line-height: ${p => p.theme.text.cardTitle.lineHeight}; color: ${p => p.theme.subText}; flex: 0 1 auto; margin: 0; `;