react-data-grid
December 3, 2019 · View on GitHub
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
divwith its size+position and event listeners - Its implementation will look like this:
return ( <div className="rdg-cell" style={style} {...eventHandlers}> {column.cellContentRenderer(cellContentProps)} </div> );
- Only renders the top
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.memoandReact.PureComponentusage. - 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} />;
- Optional, will default to
CellContent:- We might export various default
CellContentrenderers, for example:- one with formatter support only
- one with tree support
- one with cell actions
- and so on...
- We might export various default
- There is hope that we can clean up many props/options/types, like
RowGroupMetaDataperhaps. - Deprecations:
- Formatters?
- Column events?
- Once we're done replacing formatters and the default cell renderer, we could update
getVerticalRangeToRenderto only render the visible rows ±1 overscan, and remove therenderBatchSizeprop, or tweak it, as we won't need this performance optimization/workaround anymore.