flatList 在 react native 中的性能问题
Performance issue of flatList in react native
我试过 flatlist,但它在 android 中有一些性能问题。
当我向下滚动时,它加载了列表。但之后,它在向上滚动时显示空白。
到达屏幕末尾后,它会停一会儿,然后加载数据。为什么它不在底部显示加载器(activity 指示器)?为什么 onEndReached 和 onEndReachedThreshold 不起作用?
请看视频here
我的代码:
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
FlatList,
ActivityIndicator,
} from 'react-native';
import { List, ListItem, SearchBar } from "react-native-elements";
export default class FlatListExample extends Component
{
constructor(props) {
super(props);
this.state = {
loading: false,
data: [],
page: 1,
seed: 1,
error: null,
refreshing: false,
};
}
componentDidMount() {
this.makeRemoteRequest();
}
makeRemoteRequest = () => {
const { page, seed } = this.state;
const url = `https://randomuser.me/api/?seed=${seed}&page=${page}&results=20`;
console.log('url', url);
this.setState({ loading: true });
setTimeout(()=>{
fetch(url)
.then(res => res.json())
.then(res => {
this.setState({
data: [...this.state.data, ...res.results],
error: res.error || null,
loading: false,
refreshing: false
});
})
.catch(error => {
this.setState({ error, loading: false });
});
},0);
};
renderFooter = () => {
if (!this.state.loading) return null;
return (
<View
style={{
paddingVertical: 20,
borderTopWidth: 1,
borderColor: "#CED0CE"
}}
>
<ActivityIndicator animating size="large" />
</View>
);
};
handleLoadMore = () =>{
this.setState({
page:this.state.page + 1,
},()=>{
this.makeRemoteRequest();
})
}
render() {
return (
<FlatList
data={this.state.data}
renderItem={({ item }) => (
<ListItem
roundAvatar
title={`${item.name.first} ${item.name.last}`}
subtitle={item.email}
avatar={{ uri: item.picture.thumbnail }}
/>
)}
keyExtractor={item => item.email}
ListFooterComponent={this.renderFooter}
onEndReached={this.handleLoadMore}
onEndReachedThreshold={50}
/>
);
}
}
AppRegistry.registerComponent('FlatListExample', () => FlatListExample);
我注意到您没有设置 initialNumToRender
。来自文档:
initialNumToRender: number
How many items to render in the initial batch. This should be enough
to fill the screen but not much more. Note these items will never be
unmounted as part of the windowed rendering in order to improve
perceived performance of scroll-to-top actions.
因此,您需要估计在任何给定时间您希望看到多少个单元格并将其设置为该值。如果您还没有更新到最新的 react-native,我也会推荐您,其中包括对 FlatList 组件的各种改进。
我试过 flatlist,但它在 android 中有一些性能问题。
当我向下滚动时,它加载了列表。但之后,它在向上滚动时显示空白。
到达屏幕末尾后,它会停一会儿,然后加载数据。为什么它不在底部显示加载器(activity 指示器)?为什么 onEndReached 和 onEndReachedThreshold 不起作用?
请看视频here
我的代码:
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
FlatList,
ActivityIndicator,
} from 'react-native';
import { List, ListItem, SearchBar } from "react-native-elements";
export default class FlatListExample extends Component
{
constructor(props) {
super(props);
this.state = {
loading: false,
data: [],
page: 1,
seed: 1,
error: null,
refreshing: false,
};
}
componentDidMount() {
this.makeRemoteRequest();
}
makeRemoteRequest = () => {
const { page, seed } = this.state;
const url = `https://randomuser.me/api/?seed=${seed}&page=${page}&results=20`;
console.log('url', url);
this.setState({ loading: true });
setTimeout(()=>{
fetch(url)
.then(res => res.json())
.then(res => {
this.setState({
data: [...this.state.data, ...res.results],
error: res.error || null,
loading: false,
refreshing: false
});
})
.catch(error => {
this.setState({ error, loading: false });
});
},0);
};
renderFooter = () => {
if (!this.state.loading) return null;
return (
<View
style={{
paddingVertical: 20,
borderTopWidth: 1,
borderColor: "#CED0CE"
}}
>
<ActivityIndicator animating size="large" />
</View>
);
};
handleLoadMore = () =>{
this.setState({
page:this.state.page + 1,
},()=>{
this.makeRemoteRequest();
})
}
render() {
return (
<FlatList
data={this.state.data}
renderItem={({ item }) => (
<ListItem
roundAvatar
title={`${item.name.first} ${item.name.last}`}
subtitle={item.email}
avatar={{ uri: item.picture.thumbnail }}
/>
)}
keyExtractor={item => item.email}
ListFooterComponent={this.renderFooter}
onEndReached={this.handleLoadMore}
onEndReachedThreshold={50}
/>
);
}
}
AppRegistry.registerComponent('FlatListExample', () => FlatListExample);
我注意到您没有设置 initialNumToRender
。来自文档:
initialNumToRender: number
How many items to render in the initial batch. This should be enough to fill the screen but not much more. Note these items will never be unmounted as part of the windowed rendering in order to improve perceived performance of scroll-to-top actions.
因此,您需要估计在任何给定时间您希望看到多少个单元格并将其设置为该值。如果您还没有更新到最新的 react-native,我也会推荐您,其中包括对 FlatList 组件的各种改进。