我正在尝试使用RN0.43中的FlatList在3列中渲染〜250个图像的列表,并且我在FlatList的onLayout函数中更改图像的宽度以适合屏幕的宽度。
初始性能还可以,但是在向上/向下滚动一些后,有时需要一秒钟或2秒才能显示图像。
如果我改为屏幕方向则更糟糕,更新屏幕需要2~3秒。
一些调查结果:
,在调用FlatList.onLayout之前需要一秒或2秒
在FlatList.onLayout和图像宽度更新之后,每个图像(大约一半的列表,~150个图像;虽然只显示~15个)渲染2~4次,而render()只被调用一次。
问题:
感谢。
测试:GalaxySII(4.1.2)和Android SDK模拟器(7.1.1)
var data = [
require('./res/img/Search.png'),
require('./res/img/test - Copy.png'),
// ~250 items
...];
class app extends React.Component {
renderItem (info, width) {
console.log('renderItem', info.index);
if(width !== this.width) {
this.imageStyle = {width: width-MarginHorizontal , height: width-MarginHorizontal, resizeMode: 'contain'};
}
return (
<Image
source = {info.item}
key = {info.index}
style={this.imageStyle}/>
);
}
render() {
console.log('Test.render');
return (
<View style={{
flex: 1,
flexDirection: 'row',
justifyContent: 'flex-start',
alignItems: 'center',
backgroundColor: '#F5FCFF'
}}>
<GridList
numColumns={3}
columnWrapperStyle={{ alignItems: 'center', marginVertical: 5, justifyContent: 'space-around'}}
data={data}
renderItem={this.renderItem}
/>
</View>
);
}
}
class GridList extends Component {
onLayout(event) {
console.log('GridList.onLayout()');
let newColumnWidth = event.nativeEvent.layout.width/ this.numColumns;
this.layout = Object.assign({},event.nativeEvent.layout);
if( undefined === this.columnWidth || Math.abs(newColumnWidth - this.columnWidth) > WidthTolerance ) {
this.columnWidth = newColumnWidth;
if(this.isComponentMounted) {
this.setState({renderCount: this.state.renderCount+1});
} else {
this.state.renderCount +=1;
}
}
}
render() {
console.log('GridList.render()');
return (
<FlatList
{...(this.modifiedProps)}
renderItem={(info) => { return this.props.renderItem(info, this.columnWidth); }}>
{this.props.children}
</FlatList>
);
}
}
答案 0 :(得分:5)
免责声明:我知道这个问题已经过时了,但无论如何这是我的回答。
我的应用程序有一个包含500多个项目的列表。所以,我们达到了应用程序崩溃在流行的非坏手机上的程度。然后我做了this extensive research about performance on FlatLists.
FlatList
组件是旧ScrollView
的替代品。问题是ScrollViews一次呈现所有列表,因此它们在视觉上表现更好,但内存消耗存在折衷,导致应用程序崩溃。
所以扁平列表是必要的邪恶。它们基本上只渲染可见的项目,这是内存消耗的巨大收益,但视觉性能的痛苦,特别是对于繁重/复杂的项目,恰好是这些响应式图像的情况。
您可以实施许多策略来缓解您的问题。
使用缓存和效果图像,例如react-native-fast-image。您可以删除或缩写以释放Javascript线程的每个操作:执行此操作(每个图像都是new Image()
,因此,如果它们被缓存,则会更快地调用loaded
挂钩)
您的列表项组件是一个只读组件,应该是“哑”。根据需要实施shouldComponentUpdate() { return false }
或更加可靠的更新控制方法。这是巨大的性能提升。
删除列表附近任何位置的console.logs。他们使Javascript线程变得非常糟糕。
构建您的应用以进行制作并对其进行测试。它几乎总是快两倍或三倍。由于调试,Dev env很慢。
给予this article更好的阅读以获得更多策略。
FlatList
IS 是一个缓慢的组件。这是known, open and well documented issue。尽你所能改进它,让我们希望未来的版本可以解决这个问题。
答案 1 :(得分:0)
是的我遇到了同样的问题 - 多张图片&amp;反应原生的列表中的视频所以我删除了Flatlist而不是这个我更喜欢使用ListView快速渲染&amp;修复列表项上的可触摸性问题,但不要忘记将PureComponent设置为列表项
答案 2 :(得分:0)
您将为列表的每一行单独重新创建许多样式对象。这为JS-&gt; Native桥提供了大量流量。尝试使用样式表而不是内联样式。
答案 3 :(得分:0)
我强烈建议大家阅读下面所附链接中的文章,以优化您的单位列表。 https://reactnative.dev/docs/0.60/optimizing-flatlist-configuration
答案 4 :(得分:-1)
尝试使用keyExtractor
为每个项目设置唯一键例如:
render() {
return (
<List>
<FlatList
...
keyExtractor={item => item.email}
/>
</List>
);
}