Browse Source

ref(replays): Set estimatedRowSize and use registerChild when rendering virtual grid (#43069)

I'm not sure if this really fixes things or not. In prod the virtual
grid has trouble rendering many items, but in dev it's more reliable.

This adds some props to the virtual MultiGrid to try to help it out. 
See:
https://github.com/bvaughn/react-virtualized/blob/master/docs/CellMeasurer.md#render-props

https://github.com/bvaughn/react-virtualized/blob/master/docs/MultiGrid.md

Related to #[#43043](https://github.com/getsentry/sentry/issues/43043)
Ryan Albrecht 2 years ago
parent
commit
b74ad0db24

+ 40 - 25
static/app/views/replays/detail/network/index.tsx

@@ -11,7 +11,6 @@ import FluidHeight from 'sentry/views/replays/detail/layout/fluidHeight';
 import NetworkFilters from 'sentry/views/replays/detail/network/networkFilters';
 import NetworkHeaderCell, {
   COLUMN_COUNT,
-  HEADER_HEIGHT,
 } from 'sentry/views/replays/detail/network/networkHeaderCell';
 import NetworkTableCell from 'sentry/views/replays/detail/network/networkTableCell';
 import useNetworkFilters from 'sentry/views/replays/detail/network/useNetworkFilters';
@@ -20,6 +19,9 @@ import NoRowRenderer from 'sentry/views/replays/detail/noRowRenderer';
 import useVirtualizedGrid from 'sentry/views/replays/detail/useVirtualizedGrid';
 import type {NetworkSpan} from 'sentry/views/replays/types';
 
+const HEADER_HEIGHT = 25;
+const BODY_HEIGHT = 28;
+
 type Props = {
   networkSpans: undefined | NetworkSpan[];
   startTimestampMs: number;
@@ -56,6 +58,7 @@ function NetworkList({networkSpans, startTimestampMs}: Props) {
   const {cache, getColumnWidth, onScrollbarPresenceChange, onWrapperResize} =
     useVirtualizedGrid({
       cellMeasurer: {
+        defaultHeight: BODY_HEIGHT,
         defaultWidth: 100,
         fixedHeight: true,
       },
@@ -65,7 +68,7 @@ function NetworkList({networkSpans, startTimestampMs}: Props) {
       deps: [items, searchTerm],
     });
 
-  const renderTableRow = ({columnIndex, rowIndex, key, style, parent}: GridCellProps) => {
+  const cellRenderer = ({columnIndex, rowIndex, key, style, parent}: GridCellProps) => {
     const network = items[rowIndex - 1];
 
     return (
@@ -76,27 +79,37 @@ function NetworkList({networkSpans, startTimestampMs}: Props) {
         parent={parent}
         rowIndex={rowIndex}
       >
-        {rowIndex === 0 ? (
-          <NetworkHeaderCell
-            handleSort={handleSort}
-            index={columnIndex}
-            sortConfig={sortConfig}
-            style={style}
-          />
-        ) : (
-          <NetworkTableCell
-            columnIndex={columnIndex}
-            handleClick={handleClick}
-            handleMouseEnter={handleMouseEnter}
-            handleMouseLeave={handleMouseLeave}
-            isCurrent={network.id === current?.id}
-            isHovered={network.id === hovered?.id}
-            sortConfig={sortConfig}
-            span={network}
-            startTimestampMs={startTimestampMs}
-            style={style}
-          />
-        )}
+        {({
+          measure: _,
+          registerChild,
+        }: {
+          measure: () => void;
+          registerChild?: (element?: Element) => void;
+        }) =>
+          rowIndex === 0 ? (
+            <NetworkHeaderCell
+              ref={e => e && registerChild?.(e)}
+              handleSort={handleSort}
+              index={columnIndex}
+              sortConfig={sortConfig}
+              style={{...style, height: HEADER_HEIGHT}}
+            />
+          ) : (
+            <NetworkTableCell
+              ref={e => e && registerChild?.(e)}
+              columnIndex={columnIndex}
+              handleClick={handleClick}
+              handleMouseEnter={handleMouseEnter}
+              handleMouseLeave={handleMouseLeave}
+              isCurrent={network.id === current?.id}
+              isHovered={network.id === hovered?.id}
+              sortConfig={sortConfig}
+              span={network}
+              startTimestampMs={startTimestampMs}
+              style={{...style, height: BODY_HEIGHT}}
+            />
+          )
+        }
       </CellMeasurer>
     );
   };
@@ -110,10 +123,12 @@ function NetworkList({networkSpans, startTimestampMs}: Props) {
             {({width, height}) => (
               <MultiGrid
                 ref={gridRef}
+                cellRenderer={cellRenderer}
                 columnCount={COLUMN_COUNT}
                 columnWidth={getColumnWidth(width)}
-                cellRenderer={renderTableRow}
                 deferredMeasurementCache={cache}
+                estimatedColumnSize={width}
+                estimatedRowSize={HEADER_HEIGHT + items.length * BODY_HEIGHT}
                 fixedRowCount={1}
                 height={height}
                 noContentRenderer={() => (
@@ -128,7 +143,7 @@ function NetworkList({networkSpans, startTimestampMs}: Props) {
                 overscanColumnCount={COLUMN_COUNT}
                 overscanRowCount={5}
                 rowCount={items.length + 1}
-                rowHeight={({index}) => (index === 0 ? HEADER_HEIGHT : 28)}
+                rowHeight={({index}) => (index === 0 ? HEADER_HEIGHT : BODY_HEIGHT)}
                 width={width}
               />
             )}

+ 2 - 4
static/app/views/replays/detail/network/networkHeaderCell.tsx

@@ -1,4 +1,4 @@
-import {CSSProperties} from 'react';
+import {CSSProperties, forwardRef} from 'react';
 import styled from '@emotion/styled';
 
 import {IconArrow} from 'sentry/icons';
@@ -14,8 +14,6 @@ type Props = {
   style: CSSProperties;
 };
 
-export const HEADER_HEIGHT = 25;
-
 const COLUMNS: {
   field: SortConfig['by'];
   label: string;
@@ -68,4 +66,4 @@ const HeaderButton = styled('button')`
   }
 `;
 
-export default NetworkHeaderCell;
+export default forwardRef<HTMLButtonElement, Props>(NetworkHeaderCell);

+ 2 - 2
static/app/views/replays/detail/network/networkTableCell.tsx

@@ -1,4 +1,4 @@
-import {CSSProperties} from 'react';
+import {CSSProperties, forwardRef} from 'react';
 import styled from '@emotion/styled';
 
 import FileSize from 'sentry/components/fileSize';
@@ -176,4 +176,4 @@ const Text = styled('div')`
   overflow: hidden;
 `;
 
-export default NetworkTableCell;
+export default forwardRef<HTMLDivElement, Props>(NetworkTableCell);