Hello, I'm an iOS engineer working at Retty, Inc.
In the last few months, we have re-created our iOS application with Swift & ReactNative.
And we have decided to create the list of user's posts with ReactNative.
Lists in ReactNative
When talking about a list in ReactNative, we have three different choices.
- ListView
- FlatList & SectionList
- Third-party libraries (e.g. recyclerlistview)
FlatList & SectionList
As FlatList & SectionList is recommended by the official site of ReactNative, and because I want to show some section headers on my list, I tried SectionList first.
It has a very nice interface, and you can build a list with section headers, RefreshControl
and infinite scroll without any effort.
<SectionList
style={styles.list}
sections={sections}
extraData={this.state}
keyExtractor={this.keyExtractor}
renderSectionHeader={this.renderSectionHeader}
renderItem={this.renderItem}
enableEmptySections
legacyImplementation
stickySectionHeadersEnabled
refreshing={false}
onRefresh={this.onRefresh}
onEndReached={this.onEndReached}
/>
Just that, you can build a very "nice" list.
But the problem comes now, I found sometimes there are blank cells showing up when scrolling the list, with a very quick scroll, there will be lots of blank cells.
It's so weird, as an answer, I found that
Different from
ListView
, in order to resolve the memory issue ofListView
,FlatList
&SectionList
are built based on a virtualized listview.
The virtualized listview unmounts views that have gone out of the viewport, and it relies onScrollView
to do its layout and appropriately replaces unmounted views with blank views.
Okay, here is the reason why I can see blank cells when scrolling.
ListView
After lots of research on how to improve SectionList
(actually there is not so much information about it), I decided to give it up, and give ListView
a try.
In the latest version of ReactNative, ListView
has already been DEPRECATED.
The reason is ListView
has a memory issue when building a large list. I don't know what's the definition of "large list" here, so I decided to have a try.
Actually ListView
has almost the same interface and functionalities comparing with SectionList
.
<ListView
style={styles.list}
dataSource={this.state.dataSource}
renderSectionHeader={this.renderSectionHeader}
renderRow={this.renderRow}
enableEmptySections
stickySectionHeadersEnabled
refreshControl={
<RefreshControl
refreshing={false}
onRefresh={this.onRefresh}
/>
}
onEndReached={this.onEndReached}
/>
That's it, not many changes.
I tested it with my account, ListView
works very fine, even it's difficult to find the difference between ListView
and ListViews of pure native implementation.
At this point, I didn't know why ListView
has been deprecated, it works absolutely better than "new" SectionList
.
And we released the ListView
version to Apple store.
After a couple of days, I got several crash reports of this part. From the crash report, I found it crashes when displaying a user's post list with over 4,000 posts, and the reason is memory issue
.
By checking Xcode's memory graph, I realized that when I scroll down the list, the memory usage keeps growing. It reaches 500 MG after scrolling to over 500 posts, it's very very bad performance. And after scrolling to over 500 posts, the application crashes on an iPhone6.
Now, I know what is the "memory issue" of ListView
talking about.
After reading some source code of ListView
's implementation, I got the answer
ListView
doesn't reuse cells.- There is also no virtualization of any kind, leading to huge increase in memory usage as you scroll down a practically infinite list.
- There is one more problem is that listview listens to scroll event and renders items as you scroll down, this is great but it also means if you scroll too quickly the scroll would come to halt before items are rendered.
Oops, I shouldn't put it into production at all.
Third-party libraries
There are tons of third-party libraries, but most of them are built based on ListView
or FlatList
& SectionList
, means that no one is really resolving those problems.
There are also some libraries like recyclerlistview, they have their own implementation of the listview, but most of them have the almost same concept of the virtualized listview, which also has the same problems remaining not resolved.
Conclusion
As a very positive supporter of ReactNative, I don't like to but I have to draw a conclusion, that
It's not possible to build a large list in ReactNative!
I really hope someone can overthrow my conclusion, but now I have to decide to re-implement all the stuff in pure native.