Skip to content

Commit

Permalink
VirtualizedList optimization - refactor CellRenderer props to elimina…
Browse files Browse the repository at this point in the history
…te parentProps

Summary:
Problem:
All CellRenderers rerender every time the containing VirtualizedList is rerendered. This is due to the following:
- Lambda is created for each CellRenderer's onLayout prop on every VirtualizedList render (fixed in D35061321 (19cf702))
- CellRenderer's parentProps prop changes on every VirtualizedList render (addressed in this diff)
- FlatList recreates renderItem/ListItemComponent in FlatList._renderer

Changelog:
[Internal] - VirtualizedList optimization - refactor CellRenderer props to eliminate parentProps

Reviewed By: javache

Differential Revision: D35062323

fbshipit-source-id: 705c2f7c6c482b7813efdfdac7019a94594de590
  • Loading branch information
genkikondo authored and facebook-github-bot committed Mar 24, 2022
1 parent 19cf702 commit adb2962
Showing 1 changed file with 27 additions and 23 deletions.
50 changes: 27 additions & 23 deletions Libraries/Lists/VirtualizedList.js
Original file line number Diff line number Diff line change
Expand Up @@ -797,12 +797,17 @@ class VirtualizedList extends React.PureComponent<Props, State> {
const {
CellRendererComponent,
ItemSeparatorComponent,
ListHeaderComponent,
ListItemComponent,
data,
debug,
getItem,
getItemCount,
getItemLayout,
horizontal,
renderItem,
} = this.props;
const stickyOffset = this.props.ListHeaderComponent ? 1 : 0;
const stickyOffset = ListHeaderComponent ? 1 : 0;
const end = getItemCount(data) - 1;
let prevCellKey;
last = Math.min(end, last);
Expand All @@ -817,8 +822,11 @@ class VirtualizedList extends React.PureComponent<Props, State> {
<CellRenderer
CellRendererComponent={CellRendererComponent}
ItemSeparatorComponent={ii < end ? ItemSeparatorComponent : undefined}
ListItemComponent={ListItemComponent}
cellKey={key}
debug={debug}
fillRateHelper={this._fillRateHelper}
getItemLayout={getItemLayout}
horizontal={horizontal}
index={ii}
inversionStyle={inversionStyle}
Expand All @@ -828,10 +836,10 @@ class VirtualizedList extends React.PureComponent<Props, State> {
onCellLayout={this._onCellLayout}
onUpdateSeparators={this._onUpdateSeparators}
onUnmount={this._onCellUnmount}
parentProps={this.props}
ref={ref => {
this._cellRefs[key] = ref;
}}
renderItem={renderItem}
/>,
);
prevCellKey = key;
Expand Down Expand Up @@ -1887,8 +1895,19 @@ type CellRendererProps = {
ItemSeparatorComponent: ?React.ComponentType<
any | {highlighted: boolean, leadingItem: ?Item},
>,
ListItemComponent?: ?(React.ComponentType<any> | React.Element<any>),
cellKey: string,
debug?: ?boolean,
fillRateHelper: FillRateHelper,
getItemLayout?: (
data: any,
index: number,
) => {
length: number,
offset: number,
index: number,
...
},
horizontal: ?boolean,
index: number,
inversionStyle: ViewStyleProp,
Expand All @@ -1897,22 +1916,8 @@ type CellRendererProps = {
onCellLayout: (event: Object, cellKey: string, index: number) => void,
onUnmount: (cellKey: string) => void,
onUpdateSeparators: (cellKeys: Array<?string>, props: Object) => void,
parentProps: {
// e.g. height, y,
getItemLayout?: (
data: any,
index: number,
) => {
length: number,
offset: number,
index: number,
...
},
renderItem?: ?RenderItemType<Item>,
ListItemComponent?: ?(React.ComponentType<any> | React.Element<any>),
...
},
prevCellKey: ?string,
renderItem?: ?RenderItemType<Item>,
...
};

Expand Down Expand Up @@ -2030,14 +2035,16 @@ class CellRenderer extends React.Component<
const {
CellRendererComponent,
ItemSeparatorComponent,
ListItemComponent,
debug,
fillRateHelper,
getItemLayout,
horizontal,
item,
index,
inversionStyle,
parentProps,
renderItem,
} = this.props;
const {renderItem, getItemLayout, ListItemComponent} = parentProps;
const element = this._renderElement(
renderItem,
ListItemComponent,
Expand All @@ -2046,10 +2053,7 @@ class CellRenderer extends React.Component<
);

const onLayout =
/* $FlowFixMe[prop-missing] (>=0.68.0 site=react_native_fb) This comment
* suppresses an error found when Flow v0.68 was deployed. To see the
* error delete this comment and run Flow. */
(getItemLayout && !parentProps.debug && !fillRateHelper.enabled()) ||
(getItemLayout && !debug && !fillRateHelper.enabled()) ||
!this.props.onCellLayout
? undefined
: this._onLayout;
Expand Down

0 comments on commit adb2962

Please sign in to comment.