facebook / react-native

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

Performance Issues with React Native Bridgeless Architecture #47490

Open santhoshkumarvgds opened 2 weeks ago

santhoshkumarvgds commented 2 weeks ago

Description

The Bridgeless Architecture in React Native 0.74 and later introduces significant performance issues, particularly for apps with complex logic and high demands for UI responsiveness. Here are the main concerns:

Key Issues

1. Screen Load Times

2. UI Responsiveness and Touch Lag

3. Lazy Module Loading

Comparative Performance with Older Versions

Attempts to Improve Performance

Call for Optimizations

The React Native community and core team are urged to provide optimizations or alternative solutions to enhance performance under the bridgeless architecture.

Feedback Needed: Community support and solutions for the architectural limitations causing these performance issues.

Steps to reproduce

  1. Create a page/modal with 10-30 API calls.
  2. Test in React Native 0.74.x or later (Bridgeless).
  3. Measure load time and UI responsiveness.
  4. Compare with 0.71.8 (Async Bridge).

Expected: Slower performance in the bridgeless versions.

React Native Version

0.74+

Affected Platforms

Runtime - Android, Runtime - iOS

Areas

Bridgeless - The New Initialization Flow, Other (please specify)

Output of npx react-native info

System:
  OS: macOS 14.5
  CPU: (8) arm64 Apple M1
  Memory: 206.23 MB / 16.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 20.14.0
    path: /usr/local/bin/node
  Yarn:
    version: 1.22.19
    path: /usr/local/bin/yarn
  npm:
    version: 10.7.0
    path: /usr/local/bin/npm
  Watchman: Not Found
Managers:
  CocoaPods: Not Found
SDKs:
  iOS SDK: Not Found
  Android SDK: Not Found
IDEs:
  Android Studio: 2021.3 AI-213.7172.25.2113.9123335
  Xcode:
    version: 16.1/16B40
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.11
    path: /usr/bin/javac
  Ruby:
    version: 2.7.4
    path: /Users/santhoshkumarvgds/.rvm/rubies/ruby-2.7.4/bin/ruby
npmPackages:
  "@react-native-community/cli":
    installed: 15.0.0
    wanted: ^15.0.0
  react:
    installed: 18.3.1
    wanted: 18.3.1
  react-native:
    installed: 0.76.1
    wanted: ^0.76.0
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: false
iOS:
  hermesEnabled: Not found
  newArchEnabled: false

Stacktrace or Logs

The issue occurs when multiple API calls are made on initial screen load. The app becomes unresponsive and takes significantly longer to load the screen. Despite attempts to optimize by disabling lazy loading and using native threads, the issue persists. No crash or stack trace is generated, but the app's performance degrades considerably.

Reproducer

Reproducer: Unfortunately, I cannot provide a public repository or Expo Snack at this time. Please let me know if you would like further details or an isolated example of the issue.

Screenshots and Videos

No response

react-native-bot commented 2 weeks ago

[!WARNING] Could not parse version: We could not find or parse the version number of React Native in your issue report. Please use the template, and report your version including major, minor, and patch numbers - e.g. 0.76.2.

react-native-bot commented 2 weeks ago

[!WARNING] Could not parse version: We could not find or parse the version number of React Native in your issue report. Please use the template, and report your version including major, minor, and patch numbers - e.g. 0.76.2.

react-native-bot commented 2 weeks ago

[!WARNING] Missing reproducer: We could not detect a reproducible example in your issue report. Please provide either:

cortinico commented 2 weeks ago

Reproducer: Unfortunately, I cannot provide a public repository or Expo Snack at this time. Please let me know if you would like further details or an isolated example of the issue.

Yes we would need an isolated reproducer to look into this.

arasrezaei commented 2 weeks ago

I agree, there are lots of lags and crashes. When I turn newArch off, the app is much smoother

lovegaoshi commented 1 week ago

i know this isnt particularly helpful to most others, but i also oberved performance degradation when migrating my app to bridgeless. my sprcific issue is react-navigation drawer opening is particularly choppy and wont switch screens completely. this is not exactly the rn teams fault, but the general DX/UX of our apps are still impacted

JustJoostNL commented 1 week ago

@lovegaoshi did you manage to fix that choppy drawer animation? The new architecture heavily slows down my app, is there any timeline for fixing this?

lovegaoshi commented 1 week ago

unfortunately no. im reliant on react navigation and react native paper, and both have minor but unacceptable UX issues that i could not upgrade to the new arch with. right now im reinventing the wheel to write my own ui lib and migrate away from these ui libs.

given other important libs like rn firebase or notifee also breaks, its peobably the best to not chase the newest feature.

On Wed, Nov 13, 2024, 11:43 AM Joost @.***> wrote:

@lovegaoshi https://github.com/lovegaoshi did you manage to fix that choppy drawer animation? The new architecture heavily slows down my app, is there any timeline for fixing this?

— Reply to this email directly, view it on GitHub https://github.com/facebook/react-native/issues/47490#issuecomment-2474595117, or unsubscribe https://github.com/notifications/unsubscribe-auth/AZMOVVT3NCGMGDL4IRIDT732AOTXLAVCNFSM6AAAAABRLKPMCKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDINZUGU4TKMJRG4 . You are receiving this because you were mentioned.Message ID: @.***>

YasinAkimura commented 1 week ago

I can also confirm that the new arch is causing a few performance issues regarding responsiveness, and I think react-navigation / expo-router are not ready for the new arch yet.

I can notice a significant lag in catching touch events when doing things quickly which may indicate the blocking nature of synchronous events?

Also a few bugs where Views seem to always fade / animate when layout changes or Text with adjustToFitSize and "unacceptable" lineHeight completely bug out but these are different issues.

JustJoostNL commented 1 week ago

Yeah the navigation and the overall responsiveness is horrible for me. I really hope this gets fixed because other than the performance issues, the new architecture is very promising. @santhoshkumarvgds are you able to create a minimal reproducible example?

thespacemanatee commented 1 week ago

I just wanted to add that on our project (which is quite massive but well-maintained), we also see significant performance degradations in debug mode on RN 0.76, even with the new architecture turned off. The problem might be related to hermes, which has steadily declined in performance over the past few releases. Can anyone confirm that 0.76 + new arch disabled also causes performance regressions?

JustJoostNL commented 1 week ago

I haven't tested without the new arch. But I can confirm that it's probably related to Hermes as the JS frames are very low which makes the app unresponsive.

lovegaoshi commented 1 week ago

okay, im probably able to provide a repo soon(tm). i have a MotionLayout equivalent component just built from scratch using reanimated and gesture handler, and new arch is noticably choppier than old.

On Thu, Nov 14, 2024, 10:49 AM Joost @.***> wrote:

I haven't tested without the new arch. But I can confirm that it's probably related to Hermes as the JS frames are very low which makes the app unresponsive.

— Reply to this email directly, view it on GitHub https://github.com/facebook/react-native/issues/47490#issuecomment-2477172849, or unsubscribe https://github.com/notifications/unsubscribe-auth/AZMOVVQCYXGRUJDMZ7BAZVD2ATWENAVCNFSM6AAAAABRLKPMCKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDINZXGE3TEOBUHE . You are receiving this because you were mentioned.Message ID: @.***>

lovegaoshi commented 6 days ago

here for android. I have a MotionLayout (black bar at the bottom) that drags to expand to fullscreen. This is fluid with the old arch, new arch without expo's stack component, new arch with flatlist, but choppy with new arch and expo's stack or flashlist.

im not sure how useful this actually is, as this is an expo template (nowadays loaded with expo bloats. i used it for convenience) rather than a reproducer, and technically all react native components work as expected, just 3rd party libs are not.

not sure who to ping to get visibility.

C0rren commented 6 days ago

We have similar issues both in Android and iOS for our app running RN 0.76.2.

katche70 commented 6 days ago

Unfortunately, I have to completely agree with this. I spent the whole week, full of anticipation and euphoria, painstakingly converting our app to the new architecture. I am now completely disillusioned. There are a lot of places where you notice it's really stuck and you just can't get to the previous version on iOS. A lot of marketing for nothing. What a shame ☹️

thespacemanatee commented 6 days ago

@cortinico @cipolleschi any chance the React Native team can look into this with the reproducer from @lovegaoshi? It's not feasible for me to provide my company repo for obvious reasons, and creating a new project is not going to truly reflect the performance regressions in more complex applications. I find it hard to believe that Meta is using 0.76 internally unless it is really a case of user error, but it seems unlikely as many people are facing this issue.

To reiterate, here is my "minimally reproducing setup" on a complex application:

Performance is terrible on debug builds but seemingly faster than 0.75 on production, so the performance impact is only felt in debug mode. However, it makes for a horrendous development experience. Making changes and interactions take seconds.

I believe 0.76 has been the most insidious upgrade cycle because the changes according to the upgrade helper are minimal, but there are so many invisible moving parts under-the-hood that makes it impossible for us to have a reasonable timeline for any action items to pinpoint any sort of root cause. Many of us have to build features for our companies and upgrading should not be this tedious.

Although I greatly appreciate the work that the Meta team have put into this release, it has been an impossible one for us, and this is very worrying for the future of my company project due to the tight deprecation cycles in the React Native ecosystem.

cipolleschi commented 2 days ago

@thespacemanatee I'm so sorry to hear that it is not working for you.

I find it hard to believe that Meta is using 0.76 internally unless it is really a case of user error, but it seems unlikely as many people are facing this issue.

At Meta we use React Native from main, the latest commit available, and yes, all our internal app are using or are migrating to the New Architecture. We might have some extra fix that we shipped between the branch cut of 0.76 (beginning of September) and today, but I can't think of anything that might dramatically change the performances of the app running in Debug.

Is this happening for Android, iOS, or both of them? One thing that we saw causing slowness in builds was the NDEBUG flag. Release builds have these flag set to true to skip some extra check we run in debug that might be expensive and that can slow down the app.


Without a reproducer is pretty hard for us to do any work. The issue you are facing might be coming not from React Native core but from some external libraries you are using. We have evidence of big apps running smoothly (e.g.: Bluesky, which is a pretty big app, on Android) with the New Architecture.

Multiple people are reporting the issues, so I'm not downplaying them, I'm sure they are there and real. It would be quite helpful to try and find the minimum common denominator of the set of libraries or patterns that are causing the slowness.

thespacemanatee commented 2 days ago

@cipolleschi Thank you so much for the response.

Is this happening for Android, iOS, or both of them?

Both of them are slow in debug mode. Both are fast in production mode.

On our end, we will try to reverse engineer and determine whether an external dependency is causing this debug performance regression. The current list of dependencies we are using is reputable though as far as I can tell, comparing it against https://reactnative.directory/.

Also, CMIIW, but Bluesky is still using RN 0.74? Do they have a branch where they have validated that 0.76 + New Arch runs smoothly?

EDIT: They have a 0.76 branch that seems to be inactive currently, maybe someone from the team can chime in about the issues they are facing with upgrading.

C0rren commented 23 hours ago

Small consolation, but for those of you running react navigation as your navigation package, it appears that native stack navigators run slightly faster than "normal" stack navigators for screen transitions.

cipolleschi commented 19 hours ago

@thespacemanatee can you try something for me. On iOS, can you try to modify the node_modules/react-native/scripts/cocoapods/utils.rb file like this:

    def self.add_ndebug_flag_to_pods_in_release(installer)
        ndebug_flag = " -DNDEBUG"

        installer.aggregate_targets.each do |aggregate_target|
            aggregate_target.xcconfigs.each do |config_name, config_file|
-                is_release = config_name.downcase.include?("release") || config_name.downcase.include?("production")
-                unless is_release
-                    next
-                end
                self.add_flag_to_map_with_inheritance(config_file.attributes, 'OTHER_CPLUSPLUSFLAGS', ndebug_flag);
                self.add_flag_to_map_with_inheritance(config_file.attributes, 'OTHER_CFLAGS', ndebug_flag);

                xcconfig_path = aggregate_target.xcconfig_path(config_name)
                config_file.save_as(xcconfig_path)
            end
        end

        installer.target_installation_results.pod_target_installation_results.each do |pod_name, target_installation_result|
            target_installation_result.native_target.build_configurations.each do |config|
-                is_release = config.name.downcase.include?("release") || config.name.downcase.include?("production")
-                unless is_release
-                    next
-                end
                self.add_flag_to_map_with_inheritance(config.build_settings, 'OTHER_CPLUSPLUSFLAGS', ndebug_flag);
                self.add_flag_to_map_with_inheritance(config.build_settings, 'OTHER_CFLAGS', ndebug_flag);
            end
        end
    end

Then reinstall pods and try again?

What this does is basically to set the NDEBUG flag to every build config. This should disable some expensive runtime checks we are doing in debug mode to ensure the correctness of the framework. Those checks are disabled in production so that could be one of the causes why Debug is slower than development.


AFAIK, Bluesky made an Android release with the New Architecture that they asked users to try. I think they are also doing a phased rollout using the Play Store, but I am not completely sure.

thespacemanatee commented 18 hours ago

@cipolleschi Thanks for the suggestion but unfortunately it's still as slow as before, though at least we can probably rule out NDEBUG as the root cause.

cipolleschi commented 17 hours ago

To set expectation, I'll be off next week and @cortinico will be back on Thursday.

We will try to prioritize this once we are back.

brentvatne commented 8 hours ago

@thespacemanatee - i've been speaking regularly with the bluesky team, they intended to launch it recently but they're currently dealing with the issue of having 1 million daily new users - which is higher priority for them 😂 they've released a new arch version to beta testers on github and it has gone well.

i looked into @lovegaoshi's issue and i don't believe that there is something there that is particularly actionable on react-native's side yet - this hasn't been isolated to react-native itself, we need to rule out whether this is an issue with reanimated or not.

thespacemanatee commented 7 hours ago

@brentvatne To be clear, RN 0.76 is fast in production. It's the debug experience that is very slow for us. It's also slow with the new arch disabled. Just trying to narrow it down here so we don't get off track due to the many different possible configurations. We're still looking for the erroneous dependency (if any) in our project.

brentvatne commented 5 hours ago

@thespacemanatee - i see. it seems like that is worth its own issue - it's difficult to keep track when a single issue about a broad topic like "performance" has several subplots introduced by tangential experiences :)