Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Very long re-rendering times in 0.71.3 #36296

Closed
MichalBBBB opened this issue Feb 26, 2023 · 168 comments
Closed

Very long re-rendering times in 0.71.3 #36296

MichalBBBB opened this issue Feb 26, 2023 · 168 comments
Labels
Impact: Performance When the issue impacts the app running or build performance Needs: Author Feedback Stale There has been a lack of activity on this issue and it may be closed soon.

Comments

@MichalBBBB
Copy link

MichalBBBB commented Feb 26, 2023

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
Copy link

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

@samjayhk
Copy link

samjayhk commented Mar 2, 2023

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
Copy link

tj-mc commented Mar 4, 2023

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

@samjayhk
Copy link

samjayhk commented Mar 4, 2023

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
Copy link
Author

MichalBBBB commented Mar 4, 2023

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
Copy link

tj-mc commented Mar 5, 2023

@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
Copy link

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

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

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

@MichalBBBB
Copy link
Author

@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
Copy link

tj-mc commented Mar 7, 2023

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
Copy link

Is this on old or new architecture?

@MichalBBBB
Copy link
Author

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

@conoremclaughlin
Copy link

conoremclaughlin commented Mar 18, 2023

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
Copy link

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
Copy link

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

@tj-mc
Copy link

tj-mc commented Apr 6, 2023

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

@conoremclaughlin
Copy link

#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
Copy link

Maybe it’s related to this: b07cf33

RohovDmytro referenced this issue Apr 17, 2023
Summary:
We moved Hermes some build utils from [Hermes repo](https://github.com/facebook/hermes/tree/main/utils) to [React Navtie repo](https://github.com/facebook/react-native/tree/main/sdks/hermes-engine/utils) a while ago to have more control over them. However some paths on the CI were not updated. We continued to use old build scripts for Hermes prebuilds. Some unfortunate side effects are:
- `HERMES_ENABLE_DEBUGGER` is [hardcoded to true](https://github.com/facebook/hermes/blob/main/utils/build-apple-framework.sh#L65). That makes Hermes much slower in Release configuration.
- BUILD_TYPE is [set to Release](https://github.com/facebook/hermes/blob/main/utils/build-apple-framework.sh#L10) instead of `MinSizeRel` which inreases Hermes binary size.

This diff copies these build utils from RN to Hermes source directory before we perform Hermes build.

Changelog
[Internal]

Reviewed By: cipolleschi

Differential Revision: D44066721

fbshipit-source-id: f45ad6a31fb01c10199f69cc7bbcbbc83b793d34
@jaexplorer
Copy link

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

@efstathiosntonas
Copy link

efstathiosntonas commented Apr 18, 2023

garbage collector seems to be not collecting at all [email protected]

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
Copy link
Contributor

kelset commented Apr 19, 2023

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
Copy link

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
Copy link

efstathiosntonas commented Apr 19, 2023

@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
Copy link

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
Copy link

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: #26118 (comment)

@juanarzola
Copy link

juanarzola commented Apr 22, 2023

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.

@efstathiosntonas
Copy link

efstathiosntonas commented Jan 5, 2024

@papaschmidt the parsed-text-rn uses textRef but it's not used anywhere in the code, only as a prop so my guess it's just a leftover. I removed it from my code and it works just fine.

About the Property 'suppressHighlighting' does not exist on type '{ children: string; _matched?: boolean | undefined; }'., the typings are a little bit off since the typeof extractionRest is an object and not a string so it probably needs to be typed as TextProps, I'm looking into it.

Thank you for posting your results, I hope you've found a permanent solution.

edit: update the types like this and it will stop complaining:

type ParsedTextType = {
  _matched?: boolean;
  children: string;
  style?: StyleProp<TextStyle>;
  suppressHighlighting?: boolean; <--- added it here
};

@marcos-vinicius-mafei
Copy link

Any updates on this?

Copy link

This issue is waiting for author's feedback since 24 days. Please provide the requested feedback or this will be closed in 7 days.

1 similar comment
Copy link

This issue is waiting for author's feedback since 24 days. Please provide the requested feedback or this will be closed in 7 days.

@github-actions github-actions bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Feb 16, 2024
@tj-mc
Copy link

tj-mc commented Feb 16, 2024

Did we confidently find and fix the source or regression yet?

@github-actions github-actions bot removed the Stale There has been a lack of activity on this issue and it may be closed soon. label Feb 16, 2024
@tj-mc
Copy link

tj-mc commented Feb 26, 2024

@Almouro Do you have any further updates regarding this regression?
Please correct me if I'm wrong, it seems that so far all we know is

  • Part of the regression can be fixed by not using runtime scheduler
  • There could be some sort of issue in Hermes (?)

I appreciate that some of the benchmarking shows a regression on only lower-end devices, but this is a critical category of users to us. Even a slight regression can be hugely impactful as I'm sure you can appreciate, not all React code is written to best-practice.

My questions to the team:

  • Is there anything else the community should know about this issue (Do we have next steps still, or should we close this issue as wontfix)
  • Is there a fix pending for runtime scheduler?
  • Does the public dashboard for RN perf exist yet?
  • Does hermes have its own profiling / dashboards?
  • Does the Meta internal team face any sort of regression issues with this upgarde, or just the community?

Sorry for the questions, but we are very anxious to make this upgrade. Currently we're too far behind on versions (.69x) to wait any longer, but we are nervous to upgrade and risk a regression again.

@Almouro
Copy link
Contributor

Almouro commented Feb 29, 2024

Hi!

Thanks for the good questions, here are some updates on my side:

Public dashboard 📈

The RN performance dashboard is available here
It shows the performance of rendering a heavy FlatList across all RN versions on a low end Samsung A10s

It shows:

  • a perf regression on the JS side (+20% CPU usage) in 0.71 which was partly fixed
  • a regression on the main thread in 0.71 which was fixed
  • note that while the new architecture consumes less CPU overall, it seems to be heavier on the JS thread (at least for that scenario)

But I'm not sure if this really reflects the performance issues people are facing though.

As far as I know, Hermes doesn't have a profiling dashboard

Known issues 🐛

If there are some issues I'm forgetting, let me know and I can edit this message to add them.

Btw I'm very happy when someone also cares about performance low-end Android devices @tj-mc ! We do develop apps for TV as well at BAM (which are usually really low-end) but haven't faced any issues that haven't been fixed yet.
I don't think the Meta internal team either.

Other issues ❓

Is someone still experiencing performance regressions on RN >= 0.72.x / Expo 50, that are not fixed by applying the previous workarounds?
I'd be happy to try and investigate with anyone if you have a clear reproduction you're willing to share 🙏

Copy link

This issue is waiting for author's feedback since 24 days. Please provide the requested feedback or this will be closed in 7 days.

@github-actions github-actions bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Mar 25, 2024
@cortinico cortinico removed the Stale There has been a lack of activity on this issue and it may be closed soon. label Mar 25, 2024
@macmccann
Copy link

(Unrelated to React Native core) For future readers, in our case this was because despite React Native fixing the synchronous useEffect flushing issue, React Navigation still flushes immediate useEffects synchronously before starting the page animation. You can verify this by putting this component in a react navigation screen and navigating to it

export const MyComponent = () => {
  // this line is different from the React Native example, so the useEffect runs on first render
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    if (loading) {
      for (let i = 0; i < 1000000000; i++) {
        // Expensive function (for example filtering a large list)
      }
      setLoading(false);
    }
  }, [loading]);

  const onPress = () => setLoading(true);
  
  return (
    <TouchableOpacity onPress={onPress}>
      <Text>
        {loading ? 'Loading...' : 'Press Me'}
      </Text>
    </TouchableOpacity>
  );
}

@diegolmello
Copy link

@macmccann Can you please do an Expo Snack instead?

@tbenyon
Copy link

tbenyon commented Apr 19, 2024

#36296 (comment)

@macmccann

(Unrelated to React Native core) For future readers, in our case this was because despite React Native fixing the synchronous useEffect flushing issue, React Navigation still flushes immediate useEffects synchronously before starting the page animation. You can verify this by putting this component in a react navigation screen and navigating to it

export const MyComponent = () => {
  // this line is different from the React Native example, so the useEffect runs on first render
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    if (loading) {
      for (let i = 0; i < 1000000000; i++) {
        // Expensive function (for example filtering a large list)
      }
      setLoading(false);
    }
  }, [loading]);

  const onPress = () => setLoading(true);
  
  return (
    <TouchableOpacity onPress={onPress}>
      <Text>
        {loading ? 'Loading...' : 'Press Me'}
      </Text>
    </TouchableOpacity>
  );
}

Which version on React Native and React Navigation are you using?

Our biggest issue right now is the delay between tap and navigation starting this sounds like it could be the root cause of our issue.

Is there a workaround?

@idrakimuhamad
Copy link

#36296 (comment)

@macmccann

(Unrelated to React Native core) For future readers, in our case this was because despite React Native fixing the synchronous useEffect flushing issue, React Navigation still flushes immediate useEffects synchronously before starting the page animation. You can verify this by putting this component in a react navigation screen and navigating to it

export const MyComponent = () => {
  // this line is different from the React Native example, so the useEffect runs on first render
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    if (loading) {
      for (let i = 0; i < 1000000000; i++) {
        // Expensive function (for example filtering a large list)
      }
      setLoading(false);
    }
  }, [loading]);

  const onPress = () => setLoading(true);
  
  return (
    <TouchableOpacity onPress={onPress}>
      <Text>
        {loading ? 'Loading...' : 'Press Me'}
      </Text>
    </TouchableOpacity>
  );
}

Which version on React Native and React Navigation are you using?

Our biggest issue right now is the delay between tap and navigation starting this sounds like it could be the root cause of our issue.

Is there a workaround?

For us, we had to create a component that will only render the child when the screen is focused. We didn't apply this to all screen though, just those that seems having long pause before navigating, or certain area of a screen only. In my app, this is more severe in a mid Android phone, and some times even in iPhone but only certain screens.

export function FocusedRendered({
  hideOnBlur = false,
  children,
  fallback = <BareLoader />,
}: PropsWithChildren<{ hideOnBlur?: boolean; fallback?: React.ReactNode }>) {
  const [ready, setReady] = useState(false)

  useFocusEffect(
    useCallback(() => {
      InteractionManager.runAfterInteractions(() => {
        setReady(true)
      })

      return () => {
        // only hide the screen after any work is done
        // this mean once the screen finished navigating
        if (hideOnBlur) {
          InteractionManager.runAfterInteractions(() => {
            setReady(false)
          })
        }
      }
    }, [hideOnBlur])
  )

  if (ready) {
    return <>{children}</>
  }

  return fallback
}

// usage more or less like this.
const HomeScreen = () => {
  return (
    <FocusRendered>
      <Home />
    </FocusRendered>
  )
}

@tj-mc
Copy link

tj-mc commented May 10, 2024

We recently updated our app with 10's of thousands of users to RN 0.73.

Where we previously tried the upgrade to .7x, we saw many complaints. This time, we have had almost no issues. A few new native crashes due to some of our libraries, but overall performance is way better. From our perspective, it seems this issue is solved.

Thank you RN team for your hard work.

@wfern
Copy link
Contributor

wfern commented May 12, 2024

@tj-mc, old or new arch?

@tj-mc
Copy link

tj-mc commented May 12, 2024

Old Arch

@miallo
Copy link
Contributor

miallo commented May 23, 2024

There is an issue in hermes with Promises #41631
which is caused by sub-par performance of Array.indexOf facebook/hermes#1270
I guess the latter could be the issue for the FlatList performance as well

cc @Almouro for your nice overview #36296 (comment) :)

Copy link

This issue is waiting for author's feedback since 24 days. Please provide the requested feedback or this will be closed in 7 days.

@github-actions github-actions bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Jun 17, 2024
Copy link

This issue was closed because the author hasn't provided the requested feedback after 7 days.

Copy link

This issue was closed because it has been stalled for 7 days with no activity.

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Jun 24, 2024
@exlymex
Copy link

exlymex commented Jul 19, 2024

Hi, I have a question regarding performance issues on Android devices. We recently updated to React Native 0.74.3 (new architecture), and we are still experiencing problems on some Android devices. Specifically, on Samsung S22 running Android 14, some buttons are unresponsive, and the app crashes when tapping on inputs. Can anyone provide guidance on how to resolve these issues?

@LucasLfs2004
Copy link

I'm still having the same problem, I've updated the application from RN 0.68.2 to RN 0.74.3 and the application is slow in some situations, nothing I've tried so far has solved my problem.
Disabling Hermes didn't work either

@AndreiCalazans
Copy link
Contributor

AndreiCalazans commented Aug 20, 2024

This is starting to be a catch all for any type of performance or even crash issues. I highly suggest you create a separate issue with detailed information about your case. If you are experiencing a crash for example you should try to create a reproducible example or at very least share the crash log. If you are experiencing performance degradation I suggest you also try to create a sample app for us to reproduce or share performance profilings like Systrace calls or JS CPU proflings for us to try to help guide you in some direction.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Impact: Performance When the issue impacts the app running or build performance Needs: Author Feedback Stale There has been a lack of activity on this issue and it may be closed soon.
Projects
None yet
Development

No branches or pull requests