admin管理员组文章数量:1316351
Introduction
I am having serious performance issues with my VirtualizedList (infinite scroll)... I have been following this to improve it but still working really slow.
When I scroll down, the UI threads go from 60fps to 30fps, and the JS thread from 60fps to 10/20fps (sometimes to 0fps). On iOS (iPhone 6) it seems to go smoothy than on my Android (Samsung Galaxy S8+)
My VirtualizedList is rendering items with different heights, and it fetches the data when its end is reached. My item extends from React.PureComponent, as it is remended:
VirtualizedList: You have a large list that is slow to update - make sure your renderItem function renders ponents that follow React performance best practices like PureComponent, shouldComponentUpdate, etc. Object { "contentLength": 20720, "dt": 532, "prevDt": 2933, }
This issue es when I scroll down around 20 items...
Code
Here is the code of the VirtualizedList:
const keyExtractor = ({ id }) => id;
...
getItem = (data, index) => data[index];
getItemCount = (data) => data.length;
renderItem = ({ item, index }) => {
const {
images,
dimensions,
description,
location,
likes,
ments,
date,
} = item;
return (
<Card
images={images}
postDimensions={dimensions}
description={description}
location={location}
likes={likes}
ments={ments}
date={date}
/>
);
};
<VirtualizedList
data={data}
getItem={this.getItem}
getItemCount={this.getItemCount}
keyExtractor={keyExtractor}
listKey={listKey}
legacyImplementation={false}
numColumns={1}
renderItem={this.renderItem}
initialNumToRender={MAX_POSTS_TO_RETRIEVE_LENGTH} // 10
windowSize={32}
maxToRenderPerBatch={15}
updateCellsBatchingPeriod={50}
removeClippedSubviews={false}
ListFooterComponent={this.renderFooter}
ListEmptyComponent={ListEmptyComponent}
onEndReached={onEndReached}
onEndReachedThreshold={0.5}
/>
Pd: each item I am rendering has an unique id.
What I have tried
I have tried to implement my own getItemLayout method for the List but for some reason it doesn't work properly.
Warning: Failed frame type: The frame
frame.length
is marked as required inVirtualizedList.getItemLayout
, but its value isundefined
.
itemHeights = [];
getItemLayout = (data, index) => {
const length = this.itemHeights[index];
const offset = this.itemHeights.slice(0,index).reduce((a, c) => a + c, 0)
return {length, offset, index}
}
renderItem = ({ item, index }) => {
const {
images,
dimensions,
description,
location,
likes,
ments,
date,
} = item;
return (
<View onLayout={(event) => this.itemHeights[index] = event.nativeEvent.layout.height}>
<Card
images={images}
postDimensions={dimensions}
description={description}
location={location}
likes={likes}
ments={ments}
date={date}
/>
</View>
);
};
<VirtualizedList
data={data}
getItem={this.getItem}
getItemCount={this.getItemCount}
getItemLayout={this.getItemLayout}
keyExtractor={keyExtractor}
listKey={listKey}
legacyImplementation={false}
numColumns={1}
renderItem={this.renderItem}
initialNumToRender={MAX_POSTS_TO_RETRIEVE_LENGTH} // 10
windowSize={32}
maxToRenderPerBatch={15}
updateCellsBatchingPeriod={50}
removeClippedSubviews={false}
ListFooterComponent={this.renderFooter}
ListEmptyComponent={ListEmptyComponent}
onEndReached={onEndReached}
onEndReachedThreshold={0.5}
/>
Any ideas? I have seen that it is a mon problem but I haven't found any solution.
UPDATE
To solve the issue I was getting with getItemLayout just do:
getItemLayout = (data, index) => {
const length = this.itemHeights[index] || 0; // <----- if undefined return 0
const offset = this.itemHeights.slice(0,index).reduce((a, c) => a + c, 0)
return {length, offset, index}
}
Introduction
I am having serious performance issues with my VirtualizedList (infinite scroll)... I have been following this to improve it but still working really slow.
When I scroll down, the UI threads go from 60fps to 30fps, and the JS thread from 60fps to 10/20fps (sometimes to 0fps). On iOS (iPhone 6) it seems to go smoothy than on my Android (Samsung Galaxy S8+)
My VirtualizedList is rendering items with different heights, and it fetches the data when its end is reached. My item extends from React.PureComponent, as it is remended:
VirtualizedList: You have a large list that is slow to update - make sure your renderItem function renders ponents that follow React performance best practices like PureComponent, shouldComponentUpdate, etc. Object { "contentLength": 20720, "dt": 532, "prevDt": 2933, }
This issue es when I scroll down around 20 items...
Code
Here is the code of the VirtualizedList:
const keyExtractor = ({ id }) => id;
...
getItem = (data, index) => data[index];
getItemCount = (data) => data.length;
renderItem = ({ item, index }) => {
const {
images,
dimensions,
description,
location,
likes,
ments,
date,
} = item;
return (
<Card
images={images}
postDimensions={dimensions}
description={description}
location={location}
likes={likes}
ments={ments}
date={date}
/>
);
};
<VirtualizedList
data={data}
getItem={this.getItem}
getItemCount={this.getItemCount}
keyExtractor={keyExtractor}
listKey={listKey}
legacyImplementation={false}
numColumns={1}
renderItem={this.renderItem}
initialNumToRender={MAX_POSTS_TO_RETRIEVE_LENGTH} // 10
windowSize={32}
maxToRenderPerBatch={15}
updateCellsBatchingPeriod={50}
removeClippedSubviews={false}
ListFooterComponent={this.renderFooter}
ListEmptyComponent={ListEmptyComponent}
onEndReached={onEndReached}
onEndReachedThreshold={0.5}
/>
Pd: each item I am rendering has an unique id.
What I have tried
I have tried to implement my own getItemLayout method for the List but for some reason it doesn't work properly.
Warning: Failed frame type: The frame
frame.length
is marked as required inVirtualizedList.getItemLayout
, but its value isundefined
.
itemHeights = [];
getItemLayout = (data, index) => {
const length = this.itemHeights[index];
const offset = this.itemHeights.slice(0,index).reduce((a, c) => a + c, 0)
return {length, offset, index}
}
renderItem = ({ item, index }) => {
const {
images,
dimensions,
description,
location,
likes,
ments,
date,
} = item;
return (
<View onLayout={(event) => this.itemHeights[index] = event.nativeEvent.layout.height}>
<Card
images={images}
postDimensions={dimensions}
description={description}
location={location}
likes={likes}
ments={ments}
date={date}
/>
</View>
);
};
<VirtualizedList
data={data}
getItem={this.getItem}
getItemCount={this.getItemCount}
getItemLayout={this.getItemLayout}
keyExtractor={keyExtractor}
listKey={listKey}
legacyImplementation={false}
numColumns={1}
renderItem={this.renderItem}
initialNumToRender={MAX_POSTS_TO_RETRIEVE_LENGTH} // 10
windowSize={32}
maxToRenderPerBatch={15}
updateCellsBatchingPeriod={50}
removeClippedSubviews={false}
ListFooterComponent={this.renderFooter}
ListEmptyComponent={ListEmptyComponent}
onEndReached={onEndReached}
onEndReachedThreshold={0.5}
/>
Any ideas? I have seen that it is a mon problem but I haven't found any solution.
UPDATE
To solve the issue I was getting with getItemLayout just do:
getItemLayout = (data, index) => {
const length = this.itemHeights[index] || 0; // <----- if undefined return 0
const offset = this.itemHeights.slice(0,index).reduce((a, c) => a + c, 0)
return {length, offset, index}
}
Share
Improve this question
edited Sep 13, 2020 at 9:36
Victor Molina
asked Sep 13, 2020 at 8:26
Victor MolinaVictor Molina
2,6613 gold badges28 silver badges59 bronze badges
9
- Try to ment the images and see if that is cause of the slow rendering. It will not your problem but you will know what the source of the problem is. – D10S Commented Sep 13, 2020 at 9:05
- What do you mean by ment the images? Replacing/menting the Card ponent with an other?? – Victor Molina Commented Sep 13, 2020 at 9:11
- 1 Not the whole Card ponent but only the <Image>'s tag. This way you will have the list without images. If the performance improves you'll know its the images causing the problem – D10S Commented Sep 13, 2020 at 9:17
- Yes, it seems that the problem is with the images... When I removed this tag, the UI thread minmum value was 50fps when scrolling, and the JS thread 50fps too. I have also appreciated that the image causes the item to be removed when it goes ouside the viewport... Maybe this is because I am getting the images from my device cache (I cached them when they are rendered)... – Victor Molina Commented Sep 13, 2020 at 9:33
- 1 I'm Glad for you. Thank you for updating. – D10S Commented Sep 14, 2020 at 6:16
1 Answer
Reset to default 7If this happen to someone, just use my custom getItemLayout function and follow these steps
Using those values has worked for me.
initialNumToRender={10}
windowSize={5}
maxToRenderPerBatch={5}
updateCellsBatchingPeriod={30}
removeClippedSubviews={false}
...
onEndReachedThreshold={0.1}
Pd: my viewport is covered with 1.5 items
本文标签: javascriptReact NativeVirtualizedList You have a large list that is slow to updateStack Overflow
版权声明:本文标题:javascript - React Native - VirtualizedList: You have a large list that is slow to update - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742003188a2411430.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论