Vic*_*ina 2 javascript reactjs react-native
我的 VirtualizedList (无限滚动)遇到严重的性能问题...我一直在遵循此方法来改进它,但仍然工作得很慢。
当我向下滚动时,UI 线程从 60fps 变为 30fps,JS 线程从 60fps 变为 10/20fps(有时变为 0fps)。在 iOS (iPhone 6) 上似乎比在我的 Android (Samsung Galaxy S8+) 上运行流畅
我的 VirtualizedList 正在渲染具有不同高度的项目,并在到达末尾时获取数据。我的项目从 React.PureComponent 扩展而来,正如推荐的那样:
VirtualizedList:您有一个更新缓慢的列表 - 确保您的 renderItem 函数渲染遵循 React 性能最佳实践的组件,例如 PureComponent、shouldComponentUpdate 等。 Object { "contentLength": 20720, "dt": 532, "prevDt" :2933,}
当我向下滚动大约 20 个项目时,就会出现这个问题......
这是 VirtualizedList 的代码:
const keyExtractor = ({ id }) => id;
...
getItem = (data, index) => data[index];
getItemCount = (data) => data.length;
renderItem = ({ item, index }) => {
const {
images,
dimensions,
description,
location,
likes,
comments,
date,
} = item;
return (
<Card
images={images}
postDimensions={dimensions}
description={description}
location={location}
likes={likes}
comments={comments}
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}
/>
Run Code Online (Sandbox Code Playgroud)
Pd:我渲染的每个项目都有一个唯一的 ID。
我尝试为列表实现我自己的 getItemLayout 方法,但由于某种原因它无法正常工作。
警告:失败的帧类型:该帧
frame.length按照 中的要求进行标记VirtualizedList.getItemLayout,但其值为undefined。
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,
comments,
date,
} = item;
return (
<View onLayout={(event) => this.itemHeights[index] = event.nativeEvent.layout.height}>
<Card
images={images}
postDimensions={dimensions}
description={description}
location={location}
likes={likes}
comments={comments}
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}
/>
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?我发现这是一个常见问题,但我还没有找到任何解决方案。
要解决我在 getItemLayout 中遇到的问题,只需执行以下操作:
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}
}
Run Code Online (Sandbox Code Playgroud)
如果有人遇到这种情况,只需使用我的自定义 getItemLayout 函数并按照以下步骤操作
使用这些价值观对我来说很有效。
initialNumToRender={10}
windowSize={5}
maxToRenderPerBatch={5}
updateCellsBatchingPeriod={30}
removeClippedSubviews={false}
...
onEndReachedThreshold={0.1}
Run Code Online (Sandbox Code Playgroud)
Pd:我的视口被 1.5 个项目覆盖
| 归档时间: |
|
| 查看次数: |
7720 次 |
| 最近记录: |