title: React Virtualized Multigrid performance issues
body: <p>I am trying to make a nice Result View for looking at results from an SQL query. These results might contain thousands of results so React Virtualized was chosen to avoid rendering all the rows. The MultiGrid component was chosen so that the column names from the query are stickied to the top of the view. The component looks like this:</p>
  <p><a href="https://i.stack.imgur.com/9jbJn.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/9jbJn.png" alt="Multigrid component" /></a></p>
  <p>The MultiGrid has Dynamic Width, using Cell Measurer. The code is heavily inspired from the example <a href="https://github.com/bvaughn/react-virtualized/blob/master/source/CellMeasurer/CellMeasurer.DynamicWidthGrid.example.js" rel="nofollow noreferrer">here</a>. My problem is that the component renders really slowly, and in the cases where the component has been rendered, then hidden, and then rendered again, the entire app freezes for a minute or more. There is obviously something that is rendered that should not be, but I am unsure where the problem lies. I tried clearing the CellMeasurerCache but that did not seem to work. The code for the MultiGrid is as follows:</p>
  <pre><code>const useStyles = makeStyles((theme) =&gt; ({
    tableWrapper: {
      minHeight: 200,
      height: '100%',
      width: '100%',
      resize: 'vertical',
      overflowY: 'hidden',
      scrollbarWidth: 'none',
      paddingBottom: theme.spacing(2),
    },
    gridCell: {
      whiteSpace: 'nowrap',
      width: '100%',
      height: '100%',
      display: 'flex',
      flexDirection: 'column',
      paddingLeft: '1em',
      paddingRight: '1em',
      justifyContent: 'center',
    },
  }));
  
  export default function ResultTable() {
    const recordingContext = useContext(RecordingContext);
  
    const classes = useStyles();
  
    const result = recordingContext?.activeRecording?.queryOutput;
  
    if (!result || !result.results) {
      return (
        &lt;Typography style={{ padding: '8px 16px' }} variant=&quot;subtitle1&quot;&gt;
          No data to show
        &lt;/Typography&gt;
      );
    }
  
    const { labels, types, values } = result.results;
  
    function formatDate(d: Date) {
      let month = `${d.getMonth() + 1}`;
      let day = `${d.getDate()}`;
      const year = d.getFullYear();
  
      if (month.length &lt; 2) month = `0${month}`;
      if (day.length &lt; 2) day = `0${day}`;
  
      return [year, month, day].join('-');
    }
  
    function format(index: number, entry: unknown): string {
      let datatype = 0;
      if (types) {
        datatype = types[index];
      }
      if (datatype === 12) {
        if (typeof entry === 'number') {
          const date = new Date(Number(entry));
          return formatDate(date);
        }
        const date = new Date(String(entry));
        return formatDate(date);
      }
      return String(entry);
    }
  
    const STYLE: CSSProperties = {
      width: '100%',
      fontFamily: 'raleway',
      resize: 'none',
    };
  
    const cache = new CellMeasurerCache({
      defaultWidth: 100,
      fixedHeight: true,
    });
  
    type CellRendererType = {
      rowIndex: number;
      columnIndex: number;
      style: React.CSSProperties;
      parent: MeasuredCellParent;
    };
  
    function cellRenderer({
      rowIndex,
      parent,
      columnIndex,
      style,
    }: CellRendererType) {
      const content =
        rowIndex === 0
          ? labels[columnIndex]
          : format(columnIndex, values[rowIndex - 1][columnIndex]);
      return (
        &lt;CellMeasurer
          cache={cache}
          parent={parent}
          key={`${columnIndex}-${rowIndex}`}
          columnIndex={columnIndex}
          rowIndex={rowIndex}
        &gt;
          &lt;div
            style={style}
            key={`${columnIndex}-${rowIndex}`}
            className={classes.gridCell}
          &gt;
            {content}
          &lt;/div&gt;
        &lt;/CellMeasurer&gt;
      );
    }
    return (
      &lt;div className={classes.tableWrapper}&gt;
        &lt;div
          style={{
            minHeight: 201,
            height: '100%',
            width: '100%',
            paddingBottom: 1,
          }}
        &gt;
          &lt;AutoSizer&gt;
            {({ height, width }) =&gt; (
              &lt;MultiGrid
                cellRenderer={cellRenderer}
                columnWidth={cache.columnWidth}
                columnCount={labels.length}
                height={height}
                deferredMeasurementCache={cache}
                rowHeight={48}
                rowCount={values.length + 1}
                scrollToColumn={0}
                scrollToRow={0}
                fixedRowCount={1}
                width={width}
                style={STYLE}
                styleTopRightGrid={{
                  fontWeight: 'bold',
                  width: '100%',
                  backgroundColor: '#404040',
                  fontSize: 14,
                }}
                styleBottomRightGrid={{
                  outline: 'none',
                }}
                overscanColumnCount={0}
                overscanRowCount={20}
              /&gt;
            )}
          &lt;/AutoSizer&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    );
  }
  </code></pre>