React-native: Performance issue with large data: Cells/Rows in the <SectionList/> loading slowly on Android

Created on 12 Jul 2017  路  33Comments  路  Source: facebook/react-native

TL;DR

With large data, SectionList will:

  1. reload the same item repeatedly
  2. performance issue on Android (laggy and only update a few item per scrolling)

Is this a bug report?

YES

Have you read the Bugs section of the Contributing to React Native Guide?

YES

Environment

  1. react-native -v: 0.45.1 & 0.46.1 (I've tried both versions)
  2. node -v: v7.8.0
  3. npm -v: 4.2.0
  4. yarn --version (if you use Yarn): 0.22.0

  5. Target Platform (e.g. iOS, Android): Android

  6. Development Operating System (e.g. macOS Sierra, Windows 10): macOS
  7. Build tools (Xcode or Android Studio version, iOS or Android SDK version, if relevant): Android SDK 25.0.2

Steps to Reproduce

  1. I have a LoginCountryList component to display a SectionList:
export default class LoginCountryList extends React.Component {

  props: LoginCountryListProps;
  static defaultProps = {
    data: {},
  };

  renderRow = (rowItem: any) => {
    console.log('render row:');
    return (
      <TouchableHighlight
        onPress={() => this.props.onSelectRow(rowItem.item)}
      >
        <View style={styles.row}>
          <Text style={styles.rowLeftText}>{rowItem.item.name}</Text>
          <Text style={styles.rowRightText}>{`+${rowItem.item.ccc}`}</Text>
        </View>
      </TouchableHighlight>
    )
  };

  renderSectionHeader = (sectionItem: any) => (
    <View
      style={styles.sectionHeader}
    >
      <Text style={styles.sectionHeaderText}>{sectionItem.section.title}</Text>
    </View>
  );

  render() {

    console.log('re-render section list')
    return (
        <SectionList
          style={styles.listView}
          sections={this.props.data}
          renderItem={this.renderRow}
          renderSectionHeader={this.renderSectionHeader}
        />
    );
  }
}

// data:

const data = [
  // first section
  {
    "title": "A",
    "key": "A",
    "data": [
      // first row
      {
        "ccc": "93",
        "countryCode": "AF",
        "currencyCode": "AFN",
        "currencySymbol": "貗",
        "name": "Afghanistan",
        "key": "AF"
      },
      {
        "ccc": "355",
        "countryCode": "AL",
        "currencyCode": "ALL",
        "currencySymbol": "Lek",
        "name": "Albania",
        "key": "AL"
      },
      ...
    ]
  },
  ...
]

// Use 
<LoginCountryList data={data}/>
  1. Running on Android devices
  2. Encounter problems (see below)

Expected Behavior

  1. Scroll smoothly as running on iOS devices.
  2. The same items do not render multiple times.

Actual Behavior

  1. Only render a few new rows/cells per scrolling, not smoothly.
  2. The method renderRow would be called multiple times for the same row when mounting.

Explanation

I use the new API <SectionList/> to build a list UI, but I found issues running on Android devices.

  1. While scrolling down with SectionList, only a few new cells/rows can be displayed at once. You need to scroll SectionList down again to display the next a few new cells/rows, and wait for the next cells are ready to be displayed. It works not the same on the iOS.
  2. When reaching the last item in the SectionList, I tried to scroll up quickly to the first item in the SectionList, and it display a blank view with a few seconds till the cells are rendered.

I have hundred rows (country list) for display, and the user experience is bad. The user takes many seconds to reach the last item in the country list, and takes many seconds to show the previous rows after scrolling up quickly.

I tried to log in the renderItem callback when SectionList did display, and it calls renderItem hundred times for displaying only 15 rows in the first section.

Log a constant string render row: with hundred times when the SectionList did display:

screen shot 2017-07-12 at 17 07 46

Log the indexes of the items when the SectionList did display. The same row did render multiple times when the SectionList did display.

screen shot 2017-07-12 at 17 10 21

Did use SectionList wrongly? How do I do to fix it?

Reproducible Demo

https://github.com/xareelee/SectionListSlowRenderingOnAndroid

Bug SectionList Android Ran Commands Stale

Most helpful comment

mybe you can try this:
https://github.com/bolan9999/react-native-largelist

if it is useful for you, star me,please

All 33 comments

This issue looks like a question that would be best asked on StackOverflow.

StackOverflow is amazing for Q&A: it has a reputation system, voting, the ability to mark a question as answered. Because of the reputation system it is likely the community will see and answer your question there. This also helps us use the GitHub bug tracker for bugs only.

Will close this as this is really a question that should be asked on StackOverflow.

I did follow React-Native docs to use <SectionList/> and it acted differently on iOS and Android.

The docs doesn't demonstrate this behavior on Android, so I think it might be a bug.

I see. If you feel strongly about this being a bug, feel free to open an issue again, but please make sure to follow the bug template. Thanks!

I am experiencing this as well. Adding shouldComponentUpdate and getItemlayout can be helpful. but the FlatList/SectionList is still not usable on Android. As long as there are cells rendering happening (initial render or user scroll triggered), the user interaction or followed up cell rendering is super slow.

My use case is, I have a list of items, and user can select items on tap. Everything works fine on iOS, however, it takes a long time for Android to render cells, which blocks the rendering of the cell that user select. I always need to wait 3-5 seconds for UI to reflect the changes of the selection. If there is not rendering happening, it took about 0.25 ~ 0.5 seconds to show the selected cell. On iOS, everything is real time.

@xareelee have you solved this issue? or you have a bug report created?

@codingrhythm

UPDATE

Now I've updated this issue by fulfilling the bug report template, and I've also created a Reproducible Demo at https://github.com/xareelee/SectionListSlowRenderingOnAndroid.

How do I reopen this issue?

@codingrhythm I create a new issue for fulfilling the bug template

https://github.com/facebook/react-native/issues/15051

Try with VirtualizedList

I have the same problem with RN 0.46 on iOS

I seem to have the same issue on iOS. Have >1500 rows to render in the list and sometimes it does not render them all smoothly. It renders the first 10-15 and then freezes. After some time it renders the rest. I did not have this issue with ListView.

same.

same here

@codingrhythm thx ,it's very good

I have this issue as well. When using <SectionList> with two arrays it is incredibly slow but with one <FlatList> for each array it is rendering instantly.

<SectionList
    sections={[
        {
            data: this.props.favorites,
            renderItem: this.renderDepartures
        },
        {
            data: this.props.departures,
            renderItem: this.renderDepartures,
            title: 'departures'
        }
    ]}
    keyExtractor={item => item.journeyid}
    ItemSeparatorComponent={ListItemSeparator}
    renderSectionFooter={this.renderSectionFooter}
    getItemLayout={(data, index) => (
        { length: 51, offset: 51 * index, index }
    )}
    maxToRenderPerBatch={11}
    initialNumToRender={11}
/>
<FlatList
    data={this.props.favorites}
    renderItem={this.renderDepartures}
    keyExtractor={item => item.journeyid}
    ItemSeparatorComponent={ListItemSeparator}
    ListFooterComponent={this.ListFooterComponent}
    getItemLayout={(data, index) => (
        { length: 51, offset: 51 * index, index }
    )}
    maxToRenderPerBatch={11}
    initialNumToRender={11}
    scrollEnabled={false}
/>
<FlatList
    data={this.props.departures}
    renderItem={this.renderDepartures}
    title={'departures'}
    keyExtractor={item => item.journeyid}
    ItemSeparatorComponent={ListItemSeparator}
    getItemLayout={(data, index) => (
        { length: 51, offset: 51 * index, index }
    )}
    maxToRenderPerBatch={11}
    initialNumToRender={11}
    scrollEnabled={false}
/>

alphabetlistdemo

Getting the same problem. Both on iOS and Android. It takes a while to get rendered.
Already using PureComponent.

Well, we all get this problem. But I think the FB team has done their best on it though still unable to solve it.
We should talk about if we can find or give a tip of how to solve it. I suggest to make it a native component for better performance. Anyone has a good idea?

Does using the (deprecated but still available) ListView perform better? I really don't like the DataSource API but I'd go for it if it solves the jank I'm seeing with SectionList.

@andy-j-d Using FlatList performs alot better at least, and its not deprecated.

mybe you can try this:
https://github.com/bolan9999/react-native-largelist

if it is useful for you, star me,please

@RoarRain were you able to solve this? Can you please guide me too?
I'm already using PureComponent and getItemLayout. How should I use shouldComponentUpdate in this regard?

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as "For Discussion" or "Good first issue" and I will leave it open. Thank you for your contributions.

RN 0.56 has this bug. FLatList and SectionList backend is Scrollview on android, I think this is the key for this bug. When I scroll up and down, item was travel every time, even though it was travel before.
image

Simple item

class MyListItem extends React.PureComponent {
    _onPress = () => {
        this.props.onPressItem(this.props.id);
    };

    render() {
        const textColor = this.props.selected ? "red" : "black";
        return (
            <TouchableOpacity onPress={this._onPress}>
                <View style={{paddingLeft:10, height: ITEM_HEIGHT}}>
                    <Text style={{ color: textColor }}>
                        {this.props.title}
                    </Text>
                </View>
            </TouchableOpacity>
        );
    }
}

If it wasn't clear in @rcorrie's gif, this is also an issue on iOS, so it's not unique to Android. I have experienced this on both platforms.

Same issue

same issue

Same issue.

Same issue.

If it's a performance problem caused by listview
You can try this library
react-native-nlist

I am experiencing this as well. Adding shouldComponentUpdate and getItemlayout can be helpful. but the FlatList/SectionList is still not usable on Android. As long as there are cells rendering happening (initial render or user scroll triggered), the user interaction or followed up cell rendering is super slow.

My use case is, I have a list of items, and user can select items on tap. Everything works fine on iOS, however, it takes a long time for Android to render cells, which blocks the rendering of the cell that user select. I always need to wait 3-5 seconds for UI to reflect the changes of the selection. If there is not rendering happening, it took about 0.25 ~ 0.5 seconds to show the selected cell. On iOS, everything is real time.

Are you maintaining Data In state ?
Tried PureComponent for Item ?
Even i am Facing Performance issue with SectionList
For Me the issue is Section List Renders Each and Every Item because of that JS Thread is Busy Updating Item and do not Respond on User press on item or Responds After 2secs.

Same issue. Trying to render 200 basic items is very slow. Especially when filtering.

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as a "Discussion" or add it to the "Backlog" and I will leave it open. Thank you for your contributions.

Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please feel free to create a new issue with up-to-date information.

Was this page helpful?
0 / 5 - 0 ratings