index.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import {Fragment, useMemo} from 'react';
  2. import styled from '@emotion/styled';
  3. import EmptyMessage from 'sentry/components/emptyMessage';
  4. import Placeholder from 'sentry/components/placeholder';
  5. import {useReplayContext} from 'sentry/components/replays/replayContext';
  6. import {t} from 'sentry/locale';
  7. import {space} from 'sentry/styles/space';
  8. import useCountDomNodes from 'sentry/utils/replays/hooks/useCountDomNodes';
  9. import useCurrentHoverTime from 'sentry/utils/replays/playback/providers/useCurrentHoverTime';
  10. import DomNodesChart from 'sentry/views/replays/detail/memoryPanel/domNodesChart';
  11. import MemoryChart from 'sentry/views/replays/detail/memoryPanel/memoryChart';
  12. export default function MemoryPanel() {
  13. const {currentTime, isFetching, replay, setCurrentTime} = useReplayContext();
  14. const [currentHoverTime, setCurrentHoverTime] = useCurrentHoverTime();
  15. const memoryFrames = replay?.getMemoryFrames();
  16. const {data: frameToCount, isLoading: isDomNodeDataLoading} = useCountDomNodes({
  17. replay,
  18. });
  19. const domNodeData = useMemo(
  20. () => Array.from(frameToCount?.values() || []),
  21. [frameToCount]
  22. );
  23. const memoryChart =
  24. !replay || isFetching ? (
  25. <Placeholder height="100%" />
  26. ) : !replay || !memoryFrames?.length ? (
  27. <EmptyMessage
  28. data-test-id="replay-details-memory-tab"
  29. title={t('No memory metrics found')}
  30. description={t(
  31. 'Memory metrics are only captured within Chromium based browser sessions.'
  32. )}
  33. />
  34. ) : (
  35. <Fragment>
  36. <ChartTitle>{t('Heap Size')}</ChartTitle>
  37. <MemoryChart
  38. currentHoverTime={currentHoverTime}
  39. currentTime={currentTime}
  40. durationMs={replay.getDurationMs()}
  41. memoryFrames={memoryFrames}
  42. setCurrentHoverTime={setCurrentHoverTime}
  43. setCurrentTime={setCurrentTime}
  44. startTimestampMs={replay.getStartTimestampMs()}
  45. />
  46. </Fragment>
  47. );
  48. const domNodesChart =
  49. !replay || isDomNodeDataLoading ? (
  50. <Placeholder height="100%" />
  51. ) : (
  52. <Fragment>
  53. <ChartTitle>{t('DOM Nodes')}</ChartTitle>
  54. <DomNodesChart
  55. currentHoverTime={currentHoverTime}
  56. currentTime={currentTime}
  57. durationMs={replay.getDurationMs()}
  58. datapoints={domNodeData}
  59. setCurrentHoverTime={setCurrentHoverTime}
  60. setCurrentTime={setCurrentTime}
  61. startTimestampMs={replay.getStartTimestampMs()}
  62. />
  63. </Fragment>
  64. );
  65. return (
  66. <Grid>
  67. <ChartWrapper>{memoryChart}</ChartWrapper>
  68. <ChartWrapper>{domNodesChart}</ChartWrapper>
  69. </Grid>
  70. );
  71. }
  72. const Grid = styled('div')`
  73. display: grid;
  74. grid-template-rows: 1fr 1fr;
  75. grid-template-columns: 1fr;
  76. gap: ${space(1)};
  77. justify-content: center;
  78. height: 100%;
  79. `;
  80. const ChartWrapper = styled('div')`
  81. border: 1px solid ${p => p.theme.border};
  82. border-radius: ${space(0.5)};
  83. padding: ${space(1)};
  84. overflow: hidden;
  85. display: flex;
  86. flex-direction: column;
  87. & > * {
  88. flex-grow: 1;
  89. }
  90. `;
  91. const ChartTitle = styled('h5')`
  92. font-size: ${p => p.theme.fontSizeLarge};
  93. font-weight: ${p => p.theme.text.cardTitle.fontWeight};
  94. line-height: ${p => p.theme.text.cardTitle.lineHeight};
  95. color: ${p => p.theme.subText};
  96. flex: 0 1 auto;
  97. margin: 0;
  98. `;