facebook / react-native

A framework for building native applications using React
https://reactnative.dev
MIT License
117.37k stars 24.12k forks source link

Very long re-rendering times in 0.71.3 #36296

Closed MichalBBBB closed 1 month ago

MichalBBBB commented 1 year ago

For the latest update on this situation, please refer to this comment.


Description

I have a complex calendar component in my app. I previously ran it on 0.66.5, where it was really fast, but after upgrading to 0.71.3, performance dropped drastically, to the point that it is unusable.

The problem is most obvious on ios, but also appears on Android.

I used to react devtools in flipper to measure the re-render times. On ios in 0.66.5, the component re-rendered in about 7ms, on 0.71.3 it took nearly 400ms. On android the 0.66.5 took about 10ms, 0.71.3 took about 30ms.

The app uses dayjs and Flashlist, but performance was the same when switching to regular Flatlist.

React Native Version

0.71.3

Output of npx react-native info

System: OS: macOS 13.0.1 CPU: (8) arm64 Apple M1 Memory: 139.16 MB / 16.00 GB Shell: 3.3.1 - /opt/homebrew/Cellar/fish/3.3.1/bin/fish Binaries: Node: 16.13.0 - ~/.nvm/versions/node/v16.13.0/bin/node Yarn: 1.22.17 - ~/.nvm/versions/node/v16.13.0/bin/yarn npm: 8.1.0 - ~/.nvm/versions/node/v16.13.0/bin/npm Watchman: 2022.01.17.00 - /opt/homebrew/bin/watchman Managers: CocoaPods: 1.11.2 - /opt/homebrew/lib/ruby/gems/3.0.0/bin/pod SDKs: iOS SDK: Platforms: DriverKit 22.2, iOS 16.2, macOS 13.1, tvOS 16.1, watchOS 9.1 Android SDK: API Levels: 29, 30, 33 Build Tools: 29.0.2, 30.0.2, 30.0.3, 33.0.0 System Images: android-30 | Google APIs Intel x86 Atom, android-S | Google APIs ARM 64 v8a Android NDK: Not Found IDEs: Android Studio: 2020.3 AI-203.7717.56.2031.7678000 Xcode: 14.2/14C18 - /usr/bin/xcodebuild Languages: Java: 11.0.18 - /usr/bin/javac npmPackages: @react-native-community/cli: Not Found react: 18.2.0 => 18.2.0 react-native: 0.71.3 => 0.71.3 react-native-macos: Not Found npmGlobalPackages: react-native: Not Found

Steps to reproduce

Run the application and click on any day in the calendar. It has a visible lag between the click and the reaction.

Snack, code example, screenshot, or link to a repository

This is an example on 0.71.3: https://github.com/MichalBBBB/react-native-calendar This is an example on 0.66.5: https://github.com/MichalBBBB/react-native-calendar-old

SuperBigBang commented 1 year ago

The same problem, on samsung s23 animation and everything slows down

samjayhk commented 1 year ago

Hello, I also found this issue after upgrading react-native from 0.65+ to 0.71+. For example, JSON.stringify() of around 10000 characters took 0.007 second to complete on 0.65+, while 0.71+ took around 0.08 second to complete. Looking at the numbers, this took 1042% longer then old version.

For someone who may interested in hermes-engine, it will just results in more and more time cost :( (around 0.8 second).

Right now I'm trying to figure out which version of react-native will causing this issue, will keep update here.

tj-mc commented 1 year ago

Experiencing this after upgrading from 0.69.7 to 0.70.5, and 0.70.7.

samjayhk commented 1 year ago

After a long debugging, I found that it is more like the problems of react-navigation and react-redux, not because of the react-native, although it really became more slower after enabling the hermes-engine.

Anyway, after downgrading the react-navigation from v6 or v5 to v4 , the performance regression problem disappeared, even if it is based on the react-native v0.71.3 and react v18.2.0. I also tried to downgrade the react-redux to v1.3.0 or even 1.0.0, but it was not helpful for the debugging.

This looks like starting from v5 of react-navigation have changing its render() operation, which also causes different performances from v4 every render(), especially in the component which based on the connect() of react-redux.

But so far I can't find related discussions on the repository of react-navigation, and I haven't found a solution to solve this problem, because @react-navigation/native-stack is also obvious for performance regression.

Since the problem I have faced after debugging is found that not really due to react-native, I am not good at continuing to discuss it here, but if you have any ideas for this, please continue to discuss.

MichalBBBB commented 1 year ago

The problem is the sample apps I provided use neither react-navigation, nor react-redux I have already made some modifications to the original component to improve performance, but it is still at least 5 times slower than the older version without these improvements

tj-mc commented 1 year ago

@MichalBBBB Do you find that the issues are worse in low power mode? We have noticed a general reduction in performance but severe animation freezes / navigation issues on iOS in low power mode, and for all android devices.

SuperBigBang commented 1 year ago

Но до сих пор я не могу найти соответствующие обсуждения в репозитории react-navigation, и я не нашел решения для решения этой проблемы, потому что @react-navigation/native-stackэто также очевидно для снижения производительности.

Поскольку проблема, с которой я столкнулся после отладки, оказалась не совсем из-за react-native, я не могу продолжать обсуждать ее здесь, но если у вас есть какие-либо идеи на этот счет, пожалуйста, продолжайте обсуждение.

please send links to discussions in other repositories to follow the topic

MichalBBBB commented 1 year ago

@MichalBBBB Do you find that the issues are worse in low power mode? We have noticed a general reduction in performance but severe animation freezes / navigation issues on iOS in low power mode, and for all android devices.

The performance drop is always present on the iPhone, though I don't see that big of a problem on android

tj-mc commented 1 year ago

In our case the difference was most notable in startup time. From 0.69.7 to 0.70.7: Startup time doubled, and memory usages almost tripled.

keithhackbarth commented 1 year ago

Is this on old or new architecture?

MichalBBBB commented 1 year ago

Old, I just downgraded back to 0.69.8, which seems to be the newest version without these performance problems.

conoremclaughlin commented 1 year ago

After upgrading from 0.68.2 to 0.71.3, we're seeing a similar slowdown across the app but it's especially apparent on screens that re-render themselves upon focus. Here's an example of the slowdown where all libraries are the same, except react and react-native:

0.68.2 (snappy): https://www.loom.com/share/d0f9dac183f849e2ac6c6909b26a24c3 0.71.3 (significant lag on the learn tab): https://www.loom.com/share/2b73dae94d324b999d7ed31832565779

Edit: Note these were compiled jsc and hermes is unfortunately worse so there may be two issues between the hermes build artifacts that had a fix pushed and the overall architecture changes that are slowing down both.

harrisrobin commented 1 year ago

We're also experiencing a significant performance degradation ever since we upgraded from 0.6x to 0.71.x and seems like we're not the only ones #36123 .

Has anyone downgraded back to 0.6x ever since noticing this?

RohovDmytro commented 1 year ago

Is there any way to mitigate / minimize the impact? I've found the root cause way too late to downgrade.

tj-mc commented 1 year ago

Yes in our case we reverted to 0.69 and our performance was back to normal.

conoremclaughlin commented 1 year ago

36123

Yes in our case we reverted to 0.69 and our performance was back to normal.

@tj-mc which version of React are you using with 0.69? Did you only downgrade react-native?

efstathiosntonas commented 1 year ago

Maybe it’s related to this: https://github.com/facebook/react-native/commit/b07cf33279844d30920d8d46edb48b10ed5a1614

jaexplorer commented 1 year ago

I notice this mostly on IOS on a device, emulator and Android is fine.

efstathiosntonas commented 1 year ago

garbage collector seems to be not collecting at all react-native@0.71.6

I have a Flatlist used in a chat room with all the perfomance tips applied from the official docs. With Hermes enabled the memory skyrockets from ~450MB to 1.4GB while scrolling and when navigating away from this screen the memory is not de-allocated. I've disabled Hermes and the memory is going up to ~650MB and GC is working fine when navigating away.

Can anyone else confirm that there are memory leaks using Leaks measurement from Xcode Instruments?

edit: One other thing that I noticed that a cold boot of the app takes ~200MB of memory without Hermes, with Hermes the idle cold boot memory is ~500MB.

kelset commented 1 year ago

Hey everyone - a quick update on this performance issue: we've just released:

Both contain a fix for how we build Hermes' artifacts that should help address this problem. Please upgrade to those versions and let us know if they help!

SuperBigBang commented 1 year ago

Hey everyone - a quick update on this performance issue: we've just released:

Both contain a fix for how we build Hermes' artifacts that should help address this problem. Please upgrade to those versions and let us know if they help!

The application began to fly! Thank you so much, finally)) All freezes have disappeared (v0.71.7)

efstathiosntonas commented 1 year ago

@kelset just updated to 0.71.7 and the memory leak from the comment above seems to be improved but it's nowhere near the non-Hermes build low memory usage/gc. At least now I'm topping at ~900MB instead of 1.4GB on 0.71.6.

Idle memory is again at ~500MB while on non-Hermes it sits around ~200MB. Don't know if this is normal or not, can't remember what was my idle memory consumption on previous react-native versions.

ps. it doesn't matter if I use FlashList or Flatlist, the gc won't work when exiting the screen, I'm using the latest navigation and react-native-screens versions using native stack navigator.

ps2. Cleaned derived data / build folder, pod deintegrated, deleted node_modules and yarn.lock, reinstalled everything.

I'll try to create a minimal example and try to reproduce and I'll create a new issue since I'm hijacking this one.

stephenseager commented 1 year ago

Just want to add to this, I also updated to 0.71.7 and still seeing massive performance issues, when i disable hermes on both expo and react-native cli, the performance is much better.

andranikm97 commented 1 year ago

In case anyone is having pod installation issues while building their react-native iOS applications after disabling hermes, I found the comment in this issue helped me resolve them: https://github.com/facebook/react-native/issues/26118#issuecomment-525085809

juanarzola commented 1 year ago

We upgraded to 0.71.7 and didn't see any performance improvement on Android, since the change is iOS only. I am not sure if it's clear that this problem was originally reported for both platforms.

TristanH commented 1 year ago

@kelset Guys, this is really bad. Our app became basically unusably slow (even with the new 0.71.7 patches) for our users when we pushed it to them and we had to do an emergency downgrade.

If this can't be fixed properly maybe recommend developers stay on 0.69 for now?

piuholo commented 1 year ago

@TristanH We’ve encountered a similar large-scale issue in production, though only on Android. Did you see this slowness issue affect both platforms or only one of them?

TristanH commented 1 year ago

@piuholo we're still seeing issues on iOS too

cortinico commented 1 year ago

Hey all, Nicola here from the React Native core team.

To bring clarity to this issue (which is similar to #37335 and #36123): we're currently investigating this and other regression that gets reported by users on the repository.

As you all can see by the number of open issue, we can't fix all the bugs. Therefore we try to prioritize the one that are affecting the biggest group of users. This is one of them as it seems a number of users have been reporting a similar issue.

I don't have an ETA at this stage, but I'm happy to update as soon as we have more concrete results at hand.

In the meantime, we're more than happy to collaborate with member of the community in investigating this issue and try to understand where the regression comes from.

kelset commented 1 year ago

Hey folks - we released a couple more RCs for 0.72 and in them there are a few commits which should help address the perf regression: can you try RC5 and let us know if it helps?

luketgriffith commented 1 year ago

@kelset i installed .73-rc.5, and it unfortunately did not help the performance issues that we were running into. They do seem to be isolated around a few components (calendars that have lots of date-specific logic, using the react-native-calendars library). I'm attempting to see if there is an issue in those, since we ran into the problem on .69.8 as well.

kelset commented 1 year ago

@luketgriffith if you could create a repro that showcases what you are seeing, that would massively help.

luketgriffith commented 1 year ago

@kelset here is a quick repro using the same calendar library - https://github.com/luketgriffith/PerfProject. If you toggle the calendar on, you can see some lag, as well as when you quickly scroll the months. It is better here in the repro than in our actual version, so there might be something wrong with our implementation in the production app. I am still looking into that. I am also not sure how smoothly we should expect a long calendar with lots of custom logic to render - our expectations might just be off. But it was quite smooth using 0.63.3, so figured we'd investigate. Let me know if i can provide more information! Thank you for looking into this, we really appreciate it.

mango3ree commented 1 year ago

@kelset hi.any updates?

kelset commented 1 year ago

not on my end, but given @luketgriffith's repro I hope that the Meta team will be able to have a closer look at what's going on. Haven't heard anything though.

diegolmello commented 1 year ago

Maybe @cortinico has something new to share 🤞🏼

kelset commented 1 year ago

Hey folks 👋

I chatted with @cortinico and wanted to give you all an update from the maintainers perspective on the current status of this "performance regression post 0.70" trend. We've closed the other issue to try and funnel here all the conversation about it going forward to reduce noise and duplication (and avoid having to literally post the same comments in both 😅).

The main problem on our end is that currently, the reports are way too vague and usually involving many-versions-upgrades and a ton of libraries. While the fact that many people have been mentioning regressions seems to indicate an actual underlying issue, it's impossible to investigate with the data provided.

For the useEffect regression (https://github.com/facebook/react-native/issues/35778), thanks to the in-depth information provided, the Meta engineers were able to dive into that and tackle it for 0.72 - and we believe that probably a portion of the problems reported here were actually caused by it and with upgrading to 72 they will be addressed.

But if even in 0.72 there are still regressions problems, at the moment it's hard to investigate further because, again, a lack of clear repro to use to dissect the problem further.

So, what basically the Meta team needs to further investigate these "performance regression reports" is a clean repro. In particular what is needed ideally is a react-native vanilla project (you can use this) in a repository, where the starting point is on version 0.68/0.69 "performant state" and then either via a separate branch or commit, an upgrade to 70 or 71, where the regression is visible. Also, there should be an upgrade to 0.72 too that shows how the problem is not solved there either.

This to allow the person investigating the problem to switch back and forth and verify that it is indeed something caused by react-native itself (and not some side-effects of some other libraries).

While we realise that this might sound like a lot of work, it can only to be done by someone experiencing the problem 😅 an intermediate scenario we have thought of is potentially an "out-in-production" open source app being used instead of the clean repro, but there's still the need for clean "before and after" stages to investigate.

Until such repro can be provided, or other dedicated issues on specific issues that can more easily be pinpointed are opened, there's nothing that can be done from the maintainers side.

We're trying our best but this problem is very hard.

github-actions[bot] commented 1 year ago
:warning: Missing Reproducible Example
:information_source: It looks like your issue is missing a reproducible example. Please provide either:
diegolmello commented 1 year ago

From my side, I've been working on upgrading our app to 0.72 with Expo 49 beta and then I'm going to test performance. It might take a few more days because of the Reanimated 3 migration and some usual pains on the migration. I'll let you know how it goes and try to create the repro if needed. Thanks for sharing your POV ❤️

cortinico commented 1 year ago

@luketgriffith I've tried your reproducer (which is partially broken, I had to fix it to make it work) and I'm not entirely sure where exactly is the lag you're reporting (see the video). Please note that I'm testing on release

Also while investigating another issues, I've found a potential fix (https://github.com/facebook/react-native/commit/86b5b4cc34dfa8b8ec1852f2cd195361e1a9311d) but I'm unsure if this fixes this regression as, to this day, I'm still unable to reproduce this performance regression in my machine.

So as @kelset said, having a smaller repro that clearly shows where the performance regression is (with before/after videos) will greatly help here.

https://github.com/facebook/react-native/assets/3001957/7b1649d6-3d3e-4d56-a62e-598f4840e348

cortinico commented 1 year ago

Can we get someone to try 0.72.3 and report if the situation improved? I'm still waiting for a fully working reproducer so in 0.72.2 we shipped a best guess fix.

diegolmello commented 1 year ago

From my side, I've been working on upgrading our app to 0.72 with Expo 49 beta and then I'm going to test performance. It might take a few more days because of the Reanimated 3 migration and some usual pains on the migration. I'll let you know how it goes and try to create the repro if needed. Thanks for sharing your POV ❤️

Update on my side: I did a quick benchmark last week and 0.72.1 was a little bit faster than 0.71.*, but still slower than 0.69.8. It's completely tied to our app's logic and there's too many variables involved, so it's not worth sharing.

Second test I did was something like a TTI (can't really call it that), by waiting for the splash screen to close and checking for a label on the screen. It's even slower than 0.71. image Both tests using Flashlight on Redmi 9. As I said, it could be any lib, so I can't say it's RN alone.

I tried to apply Fabric with the interop, but got stuck on FastImage incompatibility.

My priority is to finish this upgrade and ship it (even though it might not be perfect), because it's going to fix a couple of other fix on our app. It's taking some time, because RN refactored WebSocket, so I need to reimplement our SSL Pinning feat. Anyway, after that I'm going to try Fabric and a repro. It could take a week or two.

AndreiBehel commented 1 year ago

@diegolmello what about 0.72.3? Is this version shows better performance that 0.72.1?

diegolmello commented 1 year ago

@AndreiBehel haven't tried it yet, but it's on my to do list for that PR.

vargajacint commented 1 year ago

It's getting even worse for me. The same code starts with 283.05MB memory consumption (version 0.71.6), now I upgraded to version 0.72.3 and the memory consumption is increased to 354.96MB

compare

RohovDmytro commented 1 year ago

I can say that after half a year of optimizations I have still a sad number of slow renders and frozen frames (via Firebase Performance). Latest upgrade to 0.72.3 sadly did not solve this either.

At this point I can't say for sure it's the react-native regression due to the scientific fact that I've lost my sanity after looking for a root cause of issue, lol.

Rendering times and skipped frames definitely look better though on the latest version during tests. So that's good. Have no idea what is going with a production build in the wild.

abitling commented 1 year ago

Issue persists on v0.73 as well.

abdi4 commented 1 year ago

Disabling hermes on both platforms has shown a massive performance increase (v72.3). Still testing but I think we'll opt out of hermes until these rendering issues are resolved

RohovDmytro commented 1 year ago

Disabling hermes on both platforms has shown a massive performance increase (v72.3). Still testing but I think we'll opt out of hermes until these rendering issues are resolved

@abdi4, What was your means of measure of rendering performance? Do you mind sharing how did you profile the difference?

diegolmello commented 1 year ago

Hey folks. Here's the repro I've promised along with benchmark results comparing 0.69.8, 0.71.7, and 0.72.3. Everything is explained on the readme. Hopefully that's good enough 🤞🏼 https://github.com/diegolmello/ReproRNBenchmark