Closed PARAGJYOTI closed 2 months ago
You can fix the issue by retrieving the data to Flatlist using the pagination technique in you backend. Please refer this video https://www.youtube.com/watch?v=rY0braBBlgw
@shanakaf that's not the problem here.
got excited about legacyImplementation but getting the error:
TypeError: Requested keys of a value that is not an object.
This error is located at: in MetroListView (at FlatList.js:632) in FlatList (at NotificationScreen.js:97) in RCTView (at View.js:78) in View (at NotificationScreen.js:92) in Screen (created by Connect(Screen)) in Connect(Screen) (at SceneView.js:17) in SceneView (at ResourceSavingSceneView.js:55) in RCTView (at View.js:78) in View (at ResourceSavingSceneView.js:48) in RCTView (at View.js:78) in View (at ResourceSavingSceneView.js:39) in ResourceSavingSceneView (at TabView.js:35) in RCTView (at View.js:78) in View (created by ViewPagerAndroid) in AndroidViewPager (at ViewPagerAndroid.android.js:238) in ViewPagerAndroid (at TabViewPagerAndroid.js:127) in TabViewPagerAndroid (at TabViewAnimated.js:71) in RCTView (at View.js:78) in View (at TabViewAnimated.js:194) in TabViewAnimated (at TabView.js:192) in TabView (at withCachedChildNavigation.js:69) in withCachedChildNavigation(TabView) (at TabNavigator.js:34) in Unknown (at createNavigator.js:13) in Navigator (at createNavigationContainer.js:226) in NavigationContainer (at SceneView.js:17) in SceneView (at DrawerScreen.js:21) in DrawerScreen (at withCachedChildNavigation.js:69) ...
no one works for me,legacyImplementation
cause ListHeaderComponent
、ListFooterComponent
not work;disableVirtualization
is deprecated.
As my current project rely a lot on FlatLists
, I took the time to create this article gathering every technique I could find around the internet that should enhance a FlatList
.
Any contribution would be really helpful!
@bamne123's solution worked for me. It is running great.
This is still happening, in android a FlatList with a few images consumes a lot of memory and is not beign released, iOS works ok
Hi Folks, Please have a look on demo for listview performance in React native with images(5mb each).
Used - RecyclerListView & FastImage
For me, adding removeClippedSubviews and choosing a relevant keyExtractor did the trick. (Eg keyExtractor = {(item) => item} for a list of unique strings).
In my case the problem was in using contentContainerStyle with paddings and this causes FlatList to go crazy. Replace paddings with header/footers solves a problem.
UPD: Header and footer doesn't solve a problem, but adding them as part of my data (first and last element) works.
using contentContainerStyle with paddings and this causes FlatList to go crazy
uhm that seems a faily "focused" issue, would you mind opening an issue dedicated to that?
Same problem here. 2 items in FlatList with images of 200kb and crash on release build.
My use case:
"react": "16.4.1"
and "react-native": "0.56.0"
react-native-navigation
which already improves perf but the list was lagging when scrolling fast. FlatList
has a numColumns={3}
. I use the keyExtractor
function.I was able to make it super smooth and fast on an Moto G6 Android phone by making the following changes:
Performance boosters
import FastImage from ["react-native-fast-image";
to replace Image
. PackagerenderItem
a React.PureComponent
.getItemLayout
to specify the size of the item.removeClippedSubviews={true}
.initialNumToRender={27}
as my view fits about 15 items (3 x 5 grid)windowSize={41}
. I turned Perf Monitor on. JS Dev Mode off. JS Minify on.
Before the changes, on the Moto G6...
After loading the app:
UI: Oscillated around 2 - 60 fps. 130 dropped so far. 6 stutters so far. JS: Oscillated between 8 - 59 fps.
While scrolling fast from top to bottom to top twice. These were the results:
UI: Oscillated around 2-58 fps. 519 dropped so far. 26 stutters so far. JS: Oscillated between 3 - 57 fps.
It got laggier as I got to the bottom of the list and even laggier as I scrolled back up.
After applying the performance boosters to the FlatList
, on the Moto G6...
After loading the app:
UI: Oscillated around 47- 59 fps. 29 dropped so far. 3 stutters so far. JS: Oscillated between 43 - 59 fps.
While scrolling fast from top to bottom to top twice. These were the results:
UI: Stable around 59 fps. 40 dropped so far. 3 stutters so far. JS: Stable around 59 fps.
The performance vastly improved!
When using Image
instead of FastImage
there is a bit of fast fading in when scrolling fast. Images at the very bottom will have its placeholder image and then load. With FastImage
the fading is gone, images load instantaneously and stay loaded in subsequent scrolls. I think FastImage
overcomes the tradeoff of gradual loading brought up by removeClippedSubviews={true}
.
Will the performance be better without images?
Removing the FastImage
element, on the Moto G6...
After loading the app:
UI: Oscillated fast around 3- 59 fps. 55 dropped so far. 3 stutters so far. JS: Oscillated between 4 - 59 fps.
While scrolling fast from top to bottom to top twice. These were the results:
UI: Stable around 59 fps. 68 dropped so far. 3 stutters so far. JS: Stable around 59 fps.
There's not much difference. It was better when having FastImage
.
I am very pleased on how performant the list became! I am sure that more can be done to improve it. But so far, without having to implement infinite scrolling techniques, the properties of FlatList
alone where fantastic for this use case.
Edit: I apologize. While scrolling with the performance boosters, the JS fps oscillate between 35 - 59 fps on the first top to bottom scroll using FastImage
. Subsequent scrolling oscillates between 49 - 59 fps.
Better than FastImage, use resizeMethod="resize" on your image to configure Fresco in android, it gives you a cpu overhead but ram goes much lower
@kelset, I see you as batman, superman, The Avengers of the React Native... Any solution? I'm diying with this. Please, save me.
Using RN 0.57.4 React 16.6.1
If I remove the Image
, Flatlist
works fine... otherwise, my app go away
I suggest that you try the solutions listed above, such as:
We are working hard on improving Android perfs from the ground up (a part of this should already land in 0.58) - but also a lot of work should be doable by changing your code. I recommend this article to better understand what in your app may be creating a ton of overhead.
@ithustle any workaround yet? I think we need to dig it deeper further simply using components as it is wont work. I have a bit complex UI i.e nested flatList. Its like each cell has its own horizontal flatList. it works great on iPhone X but breaking on low end devices due to high memory.
If it's a performance problem caused by listview You can try this library react-native-nlist
https://github.com/Flipkart/recyclerlistview solved the performance issue for me
I needed to render 300 checkbox-list-items. I naively tried to set initialNumToRender={20}
and maxToRenderPerBatch={280}
. There was a slight delay (~700ms ± 100) in the beginning, but then surprisingly I got a complete list in one maxToRenderPerBatch go and could interact with it smoothly.
P.S. Given that the (reusable) ListItem component is quite complex, as it considers several scenarios for rendering.
Make sure you test that on slower devices - not just an emulator - to get a better indication of real world performance. On Jan 14, 2019, 3:33 PM -0700, Igor Smirnov notifications@github.com, wrote:
I needed to render 300 checkbox-list-items. I naively tried to set initialNumToRender={20} and maxToRenderPerBatch={280}. There was a slight delay (~700ms ± 100) in the beginning, but then surprisingly I got a complete list in one maxToRenderPerBatch go. — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.
Also these configuration helped to achieve better performance. initialNumToRender={30} maxToRenderPerBatch={30} windowSize={101}
. I don't know, at the end it felt that it is about the best combination of the properties, perhaps, it is a quick fix for someone.
Hi, I have the same problem on my react-native V0.54 app... a FlatList with images (more than 300)... the app work fine with IOS, but crash with Android... I saw that the RAM was exploding (from ~120MB to +300MB which lead to a crash). Even when I limit the number of cards, I go from ~120MB to ~220MB only with 30 images Tests made on simulator Adroid with 1Go Ram on Android 5.1.1 - API 22
I Tried to change component, use libs more and more complex, but nothing is working... Seems that FlatList with Images (react-native image and fast-image gives the same results) lead to a hard memory explosion on Android
I went as far as I can, someone tried to resolve this ( and perhaps succeed ?)
Setting removeClippedSubviews={true}
was working for me until the 0.58 release.
With 0.59 my FlatList is lagging again on Android :(
ops, sorry: I was checking the platform using Platform.android instead of Platform.OS === 'android' (change in rn 0.59). Anyway, removeClippedSubviews is the default for android now... and in my case does the trick.
Would be nice a native Recycler FlatList, like ListView.builder() in Flutter.
Any best solution for this in flatlist?
I am also facing the issue while scrolling the scrolling performance is not good in iOS. Smoothness is not there.
@nihp Give this a shot https://github.com/Flipkart/recyclerlistview
@JanithaR Any solution which is in Flatlist itself?
There are so many things you could do. For a start, could you let me know what you have already tried?
@JanithaR My Flatlist is like below. I have added legacyImplementation, shouldComponentUpdate an soon. Kindly refer below
Also, I can able to see a white space while scrolling a large list
<FlatList
ref={(ref) => { this.flatListRef = ref; }}
data={Items}
renderItem={({ item }) => this.renderList(item)}
numColumns={2}
extraData={this.props.pagination}
keyExtractor={item => item.id}
onEndReached={this._handleMoreItems}
maxToRenderPerBatch={10}
initialNumToRender = {14}
shouldComponentUpdate= {this.shouldItemUpdate()}
onEndReachedThreshold={0.001}
ListFooterComponent={this._renderFooter}
legacyImplementation = {true}
bounces = {false}
onMomentumScrollEnd={e => this.scroll(e.nativeEvent.contentOffset)}
/>
I'm not really sure why you have this,
shouldComponentUpdate= {this.shouldItemUpdate()}
This hasn't solved any problems for me in the past.
legacyImplementation = {true}
Instead of,
renderItem={({ item }) => this.renderList(item)}
write,
renderItem={this.renderList}
Do what's said here. https://facebook.github.io/react-native/docs/optimizing-flatlist-configuration#list-items Try to make your list item components as light and restricted as possible.
I need to pass the item for sure.
renderList(item){
return (
<TouchableOpacity activeOpacity = { .5 } >
<View style={{backgroundColor: 'white', alignItems: 'center'}}>
<FastImage style={{width: Width, height: Height, margin:6}}
resizeMode={FastImage.resizeMode.contain}
source={item.uri}/>
{this.renderName(item.name)}
{this.renderClass(item.class)}
</View>
</TouchableOpacity>
)}
I am also stuck with this.
+1
+1
@nihp , @xhirazi ,@iagorm,
Have you tried Hermes or react-native-v8? I was also facing similar issued, but in my case, react-native-v8 solved it for me.
I have also published the article regarding the same.
https://medium.com/walmartlabs/react-native-memory-profiling-jsc-vs-v8-vs-hermes-1626949a653b
My app memory drop from 1.3GB to 288MB after changing to react-native-v8. It can even handle 1000 + uncompress big pic in the flat list, general response become much faster, upgrade process was amazingly smooth. This is a true life savior. It should be the default engine for android. Thx bhaskarGyan!
@naqvitalha : After breaking my head with the jank caused by FlatList, I finally moved to recyclerlistview and am really loving it. For folks who are wondering about the scroll performance difference, here's a before and after video.
FlatList sucks : https://drive.google.com/open?id=1JF8i7jVWSM3l7MU12hxWFd6glhKWpJsR
RecyclerListView is great: https://drive.google.com/open?id=1JAZRYeetDbf5tvxZCnvtM6jY5WfMDEHR
There's a weird jank when scrolling with FlatList which starts happening beyond 70 items.
@naqvitalha : Please support reverse mode for chat use cases. ScaleY: -1 approach is non-intuitive, heavy on render (because of the extra transforms causing entire list to be re-rendered if a new message is added) and also doesn't float messages on top if there's only 1 or 2 messages.
As requested, here is the source code for the RecyclerListView:
import {BaseScrollView, DataProvider, LayoutProvider, RecyclerListView} from 'recyclerlistview';
export class RecyclerViewNative extends React.PureComponent {
constructor(props) {
super(props);
this.ref = React.createRef();
const { data, inverted } = this.props;
const array = inverted ? data.slice().reverse() : data;
const dataProvider = new DataProvider((r1, r2) => {
return r1 !== r2;
}).cloneWithRows(array);
this.state = {
dataProvider,
};
this.layoutProvider = new LayoutProvider((i) => {
return this.state.dataProvider.getDataForIndex(i).type;
}, (type, dim) => {
dim.width = WINDOW_INNER_WIDTH;
dim.height = 100; // TODO: Try to get this more accurate
});
}
componentDidUpdate(prevProps, prevState, snapshot) {
const oldData = prevProps.data;
const newData = this.props.data;
// TODO: Handle message deletes as well
if (newData.length > oldData.length) {
const array = this.props.inverted ? newData.slice().reverse() : newData;
this.setState(prevState => ({
dataProvider: prevState.dataProvider.cloneWithRows(array, 0)
}));
}
}
renderRow = (type, data) => {
const { renderItem, inverted } = this.props;
const elem = renderItem(data, data.idx);
const transform = inverted ? [{ scaleY: -1 }] : [];
return <View style={{ width: '100%', transform }}>{elem}</View>;
};
render() {
const { inverted } = this.props;
const { dataProvider } = this.state;
const transform = inverted ? [{ scaleY: -1 }] : [];
return (
<View style={{ height: '100%', width: '100%', transform, paddingTop: 5 }}>
<RecyclerListView rowRenderer={this.renderRow} ref={this.ref}
forceNonDeterministicRendering={true}
dataProvider={dataProvider}
layoutProvider={this.layoutProvider}/>
</View>
);
}
}
Older FlatList I was using:
import {FlatList, View} from 'react-native';
import cnsole from 'loglevel';
export default class ScrollableList extends React.PureComponent {
constructor(props) {
super(props);
this.ref = React.createRef();
}
refElem = () => this.ref.current;
keyExtractor = ({ item, index }) => index;
renderItem = ({ item, index }) => {
const { itemRenderFn } = this.props;
return itemRenderFn(item, index);
};
onEndReached = () => {
cnsole.info('onEndReached');
};
render() {
const { style, flatListProps, inverted, data } = this.props;
const dataProp = inverted ? data.slice().reverse() : data;
const contentContainerStyle = inverted ? { flexGrow: 1, justifyContent: 'flex-end' } : {};
return (
<View style={{ ...style, display: 'flex', flexDirection: 'column' }} ref={this.ref}>
<FlatList
inverted={inverted} contentContainerStyle={contentContainerStyle}
nestedScrollEnabled={true}
data={dataProp}
renderItem={this.renderItem}
keyExtractor={this.keyExtractor}
extraData={{}}
onEndReached={this.onEndReached}
{...flatListProps}
/>
</View>
);
}
}
@gagangoku Looks great but not perfect. Unfortunately, as long as there's a bridge in RN we will have to be satisfied with this.
The solution for this would be wrapping the native RecyclerView, Flatlist is just an abstraction of reusable cells, but it uses ScrollView under the hood.
@Edit: I did wrap the RecyclerView and the performance is ridiculously higher than Flatlist.
I dont know what to do with flatlist, more than 1000 way I used but still is not fast while scrolling even when put numColumns
in horizontal mode app crash and closed.
@iagormoraes How have you used it bro
@iagormoraes How have you used it bro
I've created a native component, with view manager class and created a class to wrap a RecyclerView. the list items I created in XML layout from android as was too complex to pass each element of the list item from RN to native.
@iagormoraes thank you, but I dont know, how can I create native android ios module for react-native
@iagormoraes thank you, but I don't know, how can I create native android ios module for react-native
There is a tutorial on docs from RN but you can find other articles regarding it: https://reactnative.dev/docs/native-components-android
I spent the last several days investigating this issue for myself. Wanted to quickly document the solution/workaround I found. I won't go into too much detail on how I got to to the fix that works for me, unless anyone finds this useful and wants info. Just note that I tried a whole lot of other stuff, including every solution I see in this thread.
Solution: something to the effect of this layout below. Render a piece of text at the top of the list. You might be able to use a list header, I didn't test quite that much since this has been a multi-day bug hunt. The most basic version of this which still works for me looks roughly like this:
render() {
return (
<View style={{ display: 'flex', flex: 1, }}>
<Text style={{ fontSize: 0.1, }}> </Text>
<View style={{ flex: 1 }}>{this.renderYourList()}</View>
</View>
);
}
This made a 10+ second scroll lag fully disappear - its totally normally performant for me now. It doesn't matter what the text is, I'm using a 0.1 font size
that is colored the same as background right now in my app. But the text does have to be there - removing it or replacing the element with something else doesn't work (or at least, nothing I've found so far works). This does result in what appears to be a small margin/border on the top of the list, which works fine for me so I've not done anything more to it - I don't know if any further tweaks could effectively hide it but retain the fix.
I don't have a full understanding of why this works, I just know it worked for me. I assume it has something to do with blending, but I'm a bit too worn out to dig deeper right now. Hopefully this helps others, or helps FB address the underlying issue.
we are in 2020 and you can use the react-native flatlist prop windowSize={Number}
.
you can set your windowSize as large as you want depending on your performances tradeoffs .
for example for my case, I set windowSize to 201
which is equivalent to 201 view ports 100 below 100 above and the current one .
With this the scroll was smooth enough . try this see
Try big lists Mr. Break, Flatlist is horrible for huge lists.
Regards, Gagan, CEO @HeloProtocol, +91-9008781096, LinkedIn https://www.linkedin.com/in/gagan-deep-singh87/
On Thu, 11 Jun 2020 at 00:54, Mr Break; notifications@github.com wrote:
we are in 2020 and you can use the react-native flatlist prop windowSize={Number} . you can set your window size case large as you want depending on your performances tradeoffs
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/facebook/react-native/issues/13413#issuecomment-642209248, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAEFA4OGHNLYFA4YL7BCJXTRV7MX5ANCNFSM4DHBTFLQ .
Description
Flatlist or VirtualizedList Scroll lags horribly after 30-40 rows . I am fetching the same data on onEndReached . Upto 30 rows its looks fine , but after that scrolling drops several frames . When I disable virtualization , scroll becomes normal but but responsiveness goes away . I tried disabling virtualizing on scrolling velocity this way .
}
But again , there's problem for the unmounted Component that are removed from the views , which takes long time to show up again .
Is there any way to improve the scroll performance ?
Here's my sample code
My data is sort of large and nested object by the way . And data contains High quality Images . Per row there's two Items . But I implemented it without using numColums for testing with Virtualizedlist instead of Flatlist , but same result . Is it due to the High quality Image or I am doing something wrong ?
Additional Information