Skip to content

Instantly share code, notes, and snippets.

@nstepien

nstepien/cell.md Secret

Last active December 3, 2019 15:36
Show Gist options
  • Save nstepien/090298c3c2d94324cb332c33d82fdcfb to your computer and use it in GitHub Desktop.
Save nstepien/090298c3c2d94324cb332c33d82fdcfb to your computer and use it in GitHub Desktop.
New Cell rendering strategy

react-data-grid

Cell rendering performance is inefficient

The current cell rendering strategy is quite complex as it has to support all the features, and is split across 4+ components: Cell + CellContent + CellValue + Formatter (+ optional features in more components). This results in minimum 4 <div>s per cell, while most code paths remain unused in 99% of cases.

What I'm proposing is to make the Cell render only the container itself, and allow columns to have custom cell content renderers to allow for optmized code paths.

New Cell rendering strategy:

  • Cell:
    • Only renders the top div with its size+position and event listeners
    • Its implementation will look like this:
      return (
        <div className="rdg-cell" style={style} {...eventHandlers}>
          {column.cellContentRenderer(cellContentProps)}
        </div>
      );
  • Column.cellContentRenderer:
    • Optional, will default to (props) => React.createElement(CellContent, props);
    • Allows for greater flexibility and optimizations through customized cell content rendering.
    • Allows for props filtering, thus optimizing React.memo and React.PureComponent usage.
    • Allows for composition, e.g.: tooltipRenderer = (props) => <Tooltip text="...">{customRenderer(props)}</Tooltip>;
    • Examples:
      const cellRenderer = (props) => props.rowData[props.column.key];
      
      const cellRenderer = (props) => currencyFormatter(props.rowData[props.column.key]);
      
      const compute = _.memoize((value) => {...});
      const cellRenderer = (props) => compute(props.rowData[props.column.key]);
      
      const cellRenderer = (props) => <CustomCellContent value={props.rowData[props.column.key]} option={option} />;
  • CellContent:
    • We might export various default CellContent renderers, for example:
      • one with formatter support only
      • one with tree support
      • one with cell actions
      • and so on...
  • There is hope that we can clean up many props/options/types, like RowGroupMetaData perhaps.
  • Deprecations:
    • Formatters?
    • Column events?
  • Once we're done replacing formatters and the default cell renderer, we could update getVerticalRangeToRender to only render the visible rows ±1 overscan, and remove the renderBatchSize prop, or tweak it, as we won't need this performance optimization/workaround anymore.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment