Amrita Stha
Amrita Stha

Reputation: 3327

Performance issue of flatList in react native

I've tried flatlist but it has a bit of performance issues in android.

  1. As I scroll down, it loads the list. But afterwards, it shows blank while scrolling upwards.

  2. After reaching the end of the screen, it stops for a while and then loads the datas. Why is it not showing loader (activity indicator) at the bottom? Why is onEndReached and onEndReachedThreshold not working?

Plz have a look at the video here

https://youtu.be/5tkkEAUEAHM

My code:

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);

Upvotes: 5

Views: 4811

Answers (1)

sooper
sooper

Reputation: 6039

I've noticed that you're not setting initialNumToRender. From the docs:

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.

So you'll want to estimate how many cells you expect to be visible at any given time and set it to that. I'd also recommend if you haven't already to update to the latest react-native which includes various improvements on the FlatList component.

Upvotes: 7

Related Questions