react-native: Long text in inverted Flatlist causes huge performance drop on Android
Description
I recently upgraded to react 0.63.2 thanks to the latest Expo SDK 39. I immediately noticed that my most important FlatLists took a huge performance hit on Android (iOs seem unaffected).
After investigating, I found out that it happens when using inverted
on a FlatList that contains items with a lot of text (see snack).
The same Flatlist, with the same data, is perfectly smooth when not inverted.
I have yet to test it in production, as the latest Expo SDK is causing trouble that stops me from building the app.
React Native version:
react-native: https://github.com/expo/react-native/archive/sdk-39.0.0.tar.gz => 0.63.2
Steps To Reproduce
Provide a detailed list of steps that reproduce the issue.
- Create a Flatlist that renders items that contain a lot of text
- Set the Flatlist as inverted
Expected Results
The Flatlist should be as smooth when inverted as when normal.
Snack, code example, screenshot, or link to a repository:
About this issue
- Original URL
- State: open
- Created 4 years ago
- Reactions: 40
- Comments: 77 (12 by maintainers)
Links to this issue
Commits related to this issue
- Added ability to 'fakeInverse' the messages list via styling because of Android 13 inverted Flatlist bug. https://github.com/facebook/react-native/issues/30034 — committed to Teamworksapp/react-native-gifted-chat by skudirka-tw 2 years ago
- workaround for https://github.com/facebook/react-native/issues/30034 — committed to keybase/client by chrisnojima a year ago
- [native] Fix FlatList scroll perf issues on Android 13 Summary: See context on [this Linear issue](https://linear.app/comm/issue/ENG-793#comment-5bf0f56b) and [this React Native GitHub issue](https:/... — committed to CommE2E/comm by Ashoat a year ago
- [RN72][skip-ci] Update react-native patchfile Summary: Three changes here: 1. We don't need the Android `FlatList` hack anymore. It's [solved in 0.72.4](https://github.com/facebook/react-native/issu... — committed to CommE2E/comm by Ashoat 7 months ago
- [RN72][skip-ci] Update react-native patchfile Summary: Three changes here: 1. We don't need the Android `FlatList` hack anymore. It's [solved in 0.72.4](https://github.com/facebook/react-native/issu... — committed to CommE2E/comm by Ashoat 7 months ago
- [RN72][skip-ci] Update react-native patchfile Summary: Three changes here: 1. We don't need the Android `FlatList` hack anymore. It's [solved in 0.72.4](https://github.com/facebook/react-native/issu... — committed to CommE2E/comm by Ashoat 7 months ago
- [RN72][skip-ci] Update react-native patchfile Summary: Three changes here: 1. We don't need the Android `FlatList` hack anymore. It's [solved in 0.72.4](https://github.com/facebook/react-native/issu... — committed to CommE2E/comm by Ashoat 7 months ago
- [RN72][skip-ci] Update react-native patchfile Summary: Three changes here: 1. We don't need the Android `FlatList` hack anymore. It's [solved in 0.72.4](https://github.com/facebook/react-native/issu... — committed to CommE2E/comm by Ashoat 7 months ago
I also encounter this issue with my chat screen. It’s really hard to find to root cause.
It’s only take 10 items in the list for the performance to be hit really bad.
I’m using @cookiespam bandaid +
patch-package
to resolve the issue for now now.Here is the the content of the patch:
react-native+0.63.3.patch
@cookiespam’s workaround works. for a less intrusive fix, we could “invert” twice ourselves, once in the container and once in every cell
for ios, could just use the official
inverted
prop. however, thatscaleY
outside oftransform
seems undocumented. @cookiespam how did you come up with it? great thanks thoughFacing this issue on a Samsung Galaxy Note10 running Android 11 as well with Expo SDK 39. Didn’t happen on Android 10.
Discovered that changing the
verticallyInverted
style prop fromtransform: [{scaleY: -1}]
toscaleY: -1
inVirtualizedList
fixes it for Android, however it does not invert on iOS.For now, I have written a quick and dirty workaround to restore
scaleY
like so in my application’sindex.js
file:This allows you to continue using
scaleY
and avoid the aforementioned issue with the scroll bar being moved to the other side of theFlatList
when usingrotate
instead ofscaleY
. This works fine in React Native 0.70.x, but might break in the future if support for the property is removed from the native AndroidView
code.@MayheMatan try this
index.js (in your app)
Then patch RN 0.71 (react-native+0.71.1.patch)
The fix is part of RN 0.72.4, you can upgrade and test 😊
The
scaleY
style does not work on react 0.70.0https://github.com/facebook/react-native/issues/34607
But
transform: [{ rotate: '180deg' }],
does the trick!Wow wow wow thank you guys this fix is a lifesaver !!! 🙏
I was actually trying to replace my FlatList by a ScrollView to see where the issue was coming from and noticed then that without inverting the FlatList the performance was fine.
Now I can keep my FlatList inverted, it works exactly same as before without changing any other props and I’m going from horrible 40-50fps (since updating to Android 11) to butter smooth 90fps 😍
the solution proposed by @vinceplusplus is what I will be using:
Is someone considered making a pull request with @cookiespam and @pqkluan’s patch? I could make one in a couple of days when I get some free time but I also don’t want to steal your moment of glory haha
Still facing this in 0.71. This is an issue for all chat-like applications
In case it’s helpful to anybody, here’s the latest that’s necessary for an inverted list to play nice on Android 13 with React Native 0.70: https://phab.comm.dev/D6193
@vinceplusplus
I was just trying to invert the
FlatList
on my own without using theinverted
prop and somehow accidentally usedscaleY
(was googling how to invert something using css) which had been deprecated.A fix for this has landed on
main
already:We are working on getting these commits in a next upcoming v0.72+ version. Meanwhile you can try apply the diffs from the commit 😊
This saved my day
What about RN 0.71? Same issue?
Yes, same issue. Tested on samsung galaxy S20 Note - Android 13.
Not entirely sure, but I think this PR fixes this issue as well!
Bottom refreshControl
For those who want to keep the refresh control at the bottom, you can wrap your flatlist in a view with scaleY:-1 instead of putting the style into the flat list.
Hey @divonelnc thanks for the investigation! I noticed the same issue when running your example.
Throwing a transform style on the flatlist and children of
scaleY: -1
also had performance issues for us on Android. However, rotating the list and children180deg
didn’t seem to have the same problem and kept the “inverted” functionality.resolved my issue on
react-native-gifted-chat
with the solution from @pqkluanAs @nero2009 mention it has issue with Android devices for lag scrolling (not smooth like in iOS). If you are using
react-native-gifted-chat
and experience this issue with the RN version you have. Apply the solution mention on this thread.using the
scaleY: -1
instead oftransform: [{scaleY: -1}]
indeed seems to fix the performance issue, BUT (as usual there is a but) the refresh control becomes an issue.It renders on the top of the screen as you attempt to scroll down and in order to actually scroll you’ll need to scroll up then down to “free” the pan responder somehow.
In react native versions 0.71+ to stop performance drop on Android turn off inverted FlatList and add this : style={{transform: [{rotate: ‘180deg’}]}}, also in add this style in renderItem that is in flat list., also add this if you want to add scroll bar on the right side you can use showsVerticalScrollIndicator={false}. This fixed our chat app where we had lag on many android device when we have 10k char messages.
@devoren Flatlist is faster than Flashlist inverted…
Patch for RN 0.67.5 is here. Thanks for @pqkluan https://github.com/facebook/react-native/issues/30034#issuecomment-806396274
react-native+0.67.5.patch
VirtualizedList
is the base component thatFlatList
uses to implement the list.npx patch-package @react-native/virtualized-lists
patches/@react-native+virtualized-lists+0.72.6.patch
In React Native 0.72.3 the issue persist. Now the VirtualizedList is in another location @react-native/virtualized-lists/List
Same problem for 0.71.2
Just noting here that we observed that in Android 13 the impact of this is much, much worse than in previous versions of Android, at least in our case (a long list of messages in a chat interface.)
In Android 11 it was not so noticeable and in Android 13 it made the app completely unusable.
I think I love you, thank you!