Improve scroll to top performance
Reviewed By: yungsters, bvaughn Differential Revision: D4533070 fbshipit-source-id: 9458801aa679b830642f43be93f43bc08ef841cd
This commit is contained in:
parent
7d51580479
commit
12b228c5d9
|
@ -51,9 +51,9 @@ type ItemComponentType = ReactClass<{item: Item, index: number}>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders a virtual list of items given a data blob and accessor functions. Items that are outside
|
* Renders a virtual list of items given a data blob and accessor functions. Items that are outside
|
||||||
* the render window are 'virtualized' e.g. unmounted or never rendered in the first place. This
|
* the render window (except for the initial items at the top) are 'virtualized' e.g. unmounted or
|
||||||
* improves performance and saves memory for large data sets, but will reset state on items that
|
* never rendered in the first place. This improves performance and saves memory for large data
|
||||||
* scroll too far out of the render window.
|
* sets, but will reset state on items that scroll too far out of the render window.
|
||||||
*
|
*
|
||||||
* TODO: Note that LayoutAnimation and sticky section headers both have bugs when used with this and
|
* TODO: Note that LayoutAnimation and sticky section headers both have bugs when used with this and
|
||||||
* are therefor not supported, but new Animated impl might work?
|
* are therefor not supported, but new Animated impl might work?
|
||||||
|
@ -104,6 +104,7 @@ type OptionalProps = {
|
||||||
* Set this true while waiting for new data from a refresh.
|
* Set this true while waiting for new data from a refresh.
|
||||||
*/
|
*/
|
||||||
refreshing?: boolean,
|
refreshing?: boolean,
|
||||||
|
removeClippedSubviews?: boolean,
|
||||||
renderScrollComponent: (props: Object) => React.Element<*>,
|
renderScrollComponent: (props: Object) => React.Element<*>,
|
||||||
shouldItemUpdate: (
|
shouldItemUpdate: (
|
||||||
props: {item: Item, index: number},
|
props: {item: Item, index: number},
|
||||||
|
@ -191,6 +192,7 @@ class VirtualizedList extends React.PureComponent {
|
||||||
maxToRenderPerBatch: 10,
|
maxToRenderPerBatch: 10,
|
||||||
onEndReached: () => {},
|
onEndReached: () => {},
|
||||||
onEndReachedThreshold: 2, // multiples of length
|
onEndReachedThreshold: 2, // multiples of length
|
||||||
|
removeClippedSubviews: true,
|
||||||
renderScrollComponent: (props: Props) => {
|
renderScrollComponent: (props: Props) => {
|
||||||
if (props.onRefresh) {
|
if (props.onRefresh) {
|
||||||
invariant(
|
invariant(
|
||||||
|
@ -255,9 +257,32 @@ class VirtualizedList extends React.PureComponent {
|
||||||
this._updateCellsToRenderBatcher.schedule();
|
this._updateCellsToRenderBatcher.schedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_pushCells(cells, first, last) {
|
||||||
|
const {SeparatorComponent, data, getItem, getItemCount, keyExtractor} = this.props;
|
||||||
|
const end = getItemCount(data) - 1;
|
||||||
|
last = Math.min(end, last);
|
||||||
|
for (let ii = first; ii <= last; ii++) {
|
||||||
|
const item = getItem(data, ii);
|
||||||
|
invariant(item, 'No item for index ' + ii);
|
||||||
|
const key = keyExtractor(item, ii);
|
||||||
|
cells.push(
|
||||||
|
<CellRenderer
|
||||||
|
cellKey={key}
|
||||||
|
index={ii}
|
||||||
|
item={item}
|
||||||
|
key={key}
|
||||||
|
onLayout={this._onCellLayout}
|
||||||
|
parentProps={this.props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
if (SeparatorComponent && ii < end) {
|
||||||
|
cells.push(<SeparatorComponent key={'sep' + ii}/>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
render() {
|
render() {
|
||||||
const {FooterComponent, HeaderComponent, SeparatorComponent} = this.props;
|
const {FooterComponent, HeaderComponent} = this.props;
|
||||||
const {data, disableVirtualization, getItem, horizontal, keyExtractor} = this.props;
|
const {data, disableVirtualization, horizontal} = this.props;
|
||||||
const cells = [];
|
const cells = [];
|
||||||
if (HeaderComponent) {
|
if (HeaderComponent) {
|
||||||
cells.push(
|
cells.push(
|
||||||
|
@ -269,31 +294,18 @@ class VirtualizedList extends React.PureComponent {
|
||||||
const itemCount = this.props.getItemCount(data);
|
const itemCount = this.props.getItemCount(data);
|
||||||
if (itemCount > 0) {
|
if (itemCount > 0) {
|
||||||
_usedIndexForKey = false;
|
_usedIndexForKey = false;
|
||||||
|
const lastInitialIndex = this.props.initialNumToRender - 1;
|
||||||
const {first, last} = this.state;
|
const {first, last} = this.state;
|
||||||
if (!disableVirtualization && first > 0) {
|
this._pushCells(cells, 0, lastInitialIndex);
|
||||||
const firstOffset = this._getFrameMetricsApprox(first).offset - this._headerLength;
|
if (!disableVirtualization && first > lastInitialIndex) {
|
||||||
|
const initBlock = this._getFrameMetricsApprox(lastInitialIndex);
|
||||||
|
const firstSpace = this._getFrameMetricsApprox(first).offset -
|
||||||
|
(initBlock.offset + initBlock.length);
|
||||||
cells.push(
|
cells.push(
|
||||||
<View key="$lead_spacer" style={{[!horizontal ? 'height' : 'width']: firstOffset}} />
|
<View key="$lead_spacer" style={{[!horizontal ? 'height' : 'width']: firstSpace}} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
for (let ii = first; ii <= last; ii++) {
|
this._pushCells(cells, Math.max(lastInitialIndex + 1, first), last);
|
||||||
const item = getItem(data, ii);
|
|
||||||
invariant(item, 'No item for index ' + ii);
|
|
||||||
const key = keyExtractor(item, ii);
|
|
||||||
cells.push(
|
|
||||||
<CellRenderer
|
|
||||||
cellKey={key}
|
|
||||||
index={ii}
|
|
||||||
item={item}
|
|
||||||
key={key}
|
|
||||||
onLayout={this._onCellLayout}
|
|
||||||
parentProps={this.props}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
if (SeparatorComponent && ii < last) {
|
|
||||||
cells.push(<SeparatorComponent key={'sep' + ii}/>);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!this._hasWarned.keys && _usedIndexForKey) {
|
if (!this._hasWarned.keys && _usedIndexForKey) {
|
||||||
console.warn(
|
console.warn(
|
||||||
'VirtualizedList: missing keys for items, make sure to specify a key property on each ' +
|
'VirtualizedList: missing keys for items, make sure to specify a key property on each ' +
|
||||||
|
|
Loading…
Reference in New Issue