facebook / react-native

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

Very long re-rendering times in 0.71.3 #36296

Closed MichalBBBB closed 3 months 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

cortinico commented 1 year ago

Hey @diegolmello. Thanks for sharing that a great starting point.

Everything is explained on the readme. Hopefully that's good enough 🤞🏼

Sadly, that's not enough as it's not a reproducer (as you mention in the readme) but it's just a benchmark on your production app. Can I ask you to add a 0.70 repro branch as well?

diegolmello commented 1 year ago

@cortinico

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.

I did it because of this comment, but I understand your point. I tried to reproduce it using RN only, but what if the issue is still on RN core and happens only if you use a third party lib?

Can I ask you to add a 0.70 repro branch as well?

Sadly not. At least, not easily. We updated from 0.69 directly to 0.71. Creating a 0.70 would require a ton of work. If it's completely necessary for you to go deeper, I can do it, but I prefer to work on other stuff.

cortinico commented 1 year ago

I did it because of this comment, but I understand your point. I tried to reproduce it using RN only, but what if the issue is still on RN core and happens only if you use a third party lib?

Yeah that's exactly the point. It's hard to pinpoint if the problem is with a library you updated or is with core. Still this is a step forward.

I was asking for the 0.70 update as there are like 2000 commits between 0.69 and 0.71, and having a middle point would really help understand where the issue could be

diegolmello commented 1 year ago

@cortinico I gave it a try and 0.70 upgrade is quite straightforward. Here's your branch: repro-0.70.12. I hope it helps 🤞🏼

Maxime-Asphalte commented 1 year ago

Hello,

Any news here ? I update my project with Expo 49 / react-native 72.3 and the navigation between stack screen work properly on IOS but on Android it's very slow... There is an update in the view during the transition between parent and child screen as async datas arrive and trigger a redraw. There clearly is a freeze...

I roll back to Expo 48 / react-native 0.71.8 and it worked properly.

tj-mc commented 1 year ago

@cortinico I have created a clean reproducer that demonstrates this regression in Release mode. The repo contains a main branch on .68.7, and branches with .70.12 and .72.3 upgrades.

With this I can see that performance is best on .68.7, worst on .70.12, and somewhat in-between for .72.3, so clearly the previous fixes have made a significant improvement.

If this is not sufficient, or you need more intermediary upgrades, please let me know and I'm more than happy to update it 😄

https://github.com/tj-mc/rn-perf-repro

cortinico commented 1 year ago

@cortinico I have created a clean reproducer that demonstrates this regression in Release mode. The repo contains a main branch on .68.7, and branches with .70.12 and .72.3 upgrades.

@tj-mc This is amazing thank you! I'll look into it and pass it around for further investigation

ajsmth commented 1 year ago

FWIW I have noticed a significant drop in performance when upgrading from 0.71.8 to 0.72.3 on Android specifically

devoren commented 1 year ago

@Maxime-Asphalte agree with you, 0.72.3 on Android Due to a performance regression, even in a simple application, when returning to the previous screen using goBack from react-navigation, the UI frame rate drops to 34-40, JS drops to about 30

ajsmth commented 1 year ago

To add to the above - I suspect something is going on with the native stack from react-native-screens - I'm not using react-navigation and also am seeing perf issues

diegolmello commented 1 year ago

@ajsmth I'm not using native stack and I'm seeing those issues.

devoren commented 1 year ago

@diegolmello You're right, I also noticed that even simple js array functions like filter/map/find are a bit slower sometimes. I have flashlist and motiskeleton. List in react native tab-view and i show 4 skeletons. I see that when loading data, the first 3 skeletons are rendered, and after a delay, the 4th skeleton is rendered.😅

mango3ree commented 1 year ago

any updates?

cortinico commented 1 year ago

any updates?

Hi all, Sadly I don't have any update to share at this stage. This is still on our plate and we'll share relevant updates in this thread as soon as we have them (please refrain from asking from status updates as we'll share them as we have them).

In the meanwhile, whoever wants to investigate and share relevant information which might help the investigation, is more than welcome to do so an will be extremely valuable in understanding the problem.

diegolmello commented 1 year ago

@cortinico do you have any estimates on this?

We can't wait forever on an item that prevents us from moving on. It's choice between staying outdated or delivering a bad experience to the users. 0.69 is out of LTS already, so anyone using React Native for enterprise purposes are facing an increasing amount of risk. Upgrading to a more stable version is crucial not only for taking advantage of the latest features, but for ensuring compatibility and security.

Since 0.70 was released last September, this issue is completing 1 year in two weeks.

devoren commented 1 year ago

I don't know if it's because of this problem. But sometimes my app freezes and unresponsive on emulator for a while (never seen before) so I tried to check logcat and see this (dev mode):

app_time_stats: avg=24668.47ms min=24668.47ms max=24668.47ms count=1

24 sec... 🤔

himanshuzeptonow commented 1 year ago

any update? app startup time is almost doubled after updating to 0.71.12

AminJafarlou commented 1 year ago

Any updates on this issue? My app is currently running on 0.70.1 and I am facing all kinds of performance issues on Android. Right now version 0.72.4 is available, should I upgrade to that or downgrade to 0.69.8? which one do you suggest?

devoren commented 1 year ago

@AminJafarlou Can you downgrade and also upgrade to see performance issues? At the moment I would not recommend upgrading

devoren commented 1 year ago

I tried to downgrade my expo app to 71.8 from 72.4: before (when navigate go back): 6-20fps after (when navigate go back): 45-50fps

Kudo commented 1 year ago

for people running on expo sdk 49, we did noticed some edge regression case due to react-native 0.72 runtime scheduler. not sure if that's related but we added a way to disable the runtime scheduler in https://github.com/expo/expo/pull/23117 please try this inline config-plugin and run npx prebuild -p android --clean.

# app.config.js
const { withGradleProperties } = require("expo/config-plugins");

function disableUnstableRuntimeScheduler(config) {
  const KEY = "reactNative.unstable_useRuntimeSchedulerAlways";
  return withGradleProperties(config, (config) => {
    config.modResults = config.modResults.filter(
      (item) => !(item.type === "property" && item.key === KEY)
    );
    config.modResults.push({
      type: "property",
      key: KEY,
      value: "false",
    });
    return config;
  });
}

export default ({ config }) => {
  config.plugins = [...(config.plugins ?? []), disableUnstableRuntimeScheduler];
  return config;
};
devoren commented 1 year ago

@Kudo Thanks for the suggestion, but unfortunately it didn't help me :(

Kudo commented 1 year ago

oh no, being sad to hear that.

alright, does anyone compare the performance based on jsc? since there were many changes between react-native major versions, it's hard to say where the performance regression coming from. based on jsc, we could at least to differentiate whether the performance regression is coming from hermes or not.

devoren commented 1 year ago

@Kudo today i will try 0.71.8 and 0.72.4 on jsc

devoren commented 1 year ago

@Kudo I set hermesEnabled=false then i run expo run:android. I have this error after Bundling complete (SDK: ^49.0.8, react-native: 0.72.4)

Edit: I don't understand why this error appears. I've tried clean new/production projects. Also in SDK 48 same problem, I can't run on jsc😢

Screenshot_1693481388

devoren commented 1 year ago

@Kudo I can't run jsc so I tried Hermes again, as you can see even version 0.71.8 with Hermes has a big difference: v.0.71.8 app package json fps around 40-60:

{
  "dependencies": {
    "@expo-google-fonts/inter": "^0.2.3",
    "@gorhom/bottom-sheet": "^5.0.0-alpha.3",
    "@ptomasroos/react-native-multi-slider": "^2.2.2",
    "@react-native-assets/slider": "^7.0.2",
    "@react-native-community/netinfo": "9.3.7",
    "@react-native-picker/picker": "2.4.8",
    "@shopify/flash-list": "1.4.0",
    "@tanstack/react-query": "^4.33.0",
    "autosuggest-highlight": "^3.3.4",
    "axios": "^1.4.0",
    "compose-function": "^3.0.3",
    "dayjs": "^1.11.8",
    "expo": "~48.0.18",
    "expo-application": "~5.1.1",
    "expo-blur": "~12.2.2",
    "expo-camera": "~13.2.1",
    "expo-clipboard": "~4.1.2",
    "expo-constants": "~14.2.1",
    "expo-device": "~5.2.1",
    "expo-font": "~11.1.1",
    "expo-image": "~1.0.1",
    "expo-image-manipulator": "~11.1.1",
    "expo-image-picker": "~14.1.1",
    "expo-linear-gradient": "~12.1.2",
    "expo-linking": "~4.0.1",
    "expo-router": "^1.0.0",
    "expo-sharing": "~11.2.2",
    "expo-splash-screen": "~0.18.2",
    "expo-status-bar": "~1.4.4",
    "js-cookie": "^3.0.5",
    "moti": "^0.25.3",
    "patch-package": "^7.0.0",
    "postinstall-postinstall": "^2.1.0",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-hook-form": "^7.45.4",
    "react-imask": "^7.1.3",
    "react-native": "0.71.8",
    "react-native-collapsible": "^1.6.1",
    "react-native-collapsible-tab-view": "^6.1.4",
    "react-native-date-picker": "^4.2.13",
    "react-native-gesture-handler": "~2.9.0",
    "react-native-image-viewing": "^0.2.2",
    "react-native-keyboard-controller": "^1.6.0",
    "react-native-mmkv": "^2.10.0",
    "react-native-modal": "^13.0.1",
    "react-native-pager-view": "6.1.2",
    "react-native-ratings": "^8.1.0",
    "react-native-reanimated": "~2.14.4",
    "react-native-reanimated-carousel": "^3.5.1",
    "react-native-safe-area-context": "4.5.0",
    "react-native-screens": "~3.20.0",
    "react-native-share": "^9.2.3",
    "react-native-svg": "13.4.0",
    "react-native-tab-view": "^3.5.2",
    "react-native-text-input-mask": "^3.2.0",
    "react-native-toast-message": "^2.1.6",
    "react-native-web": "~0.18.10",
    "react-native-webview": "11.26.0",
    "react-slick": "^0.29.0",
    "slick-carousel": "^1.8.1",
    "zustand": "^4.3.8"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0",
    "@babel/plugin-proposal-export-namespace-from": "^7.18.9",
    "@types/autosuggest-highlight": "^3.2.0",
    "@types/compose-function": "^0.0.30",
    "@types/js-cookie": "^3.0.3",
    "@types/react": "~18.2.14",
    "@types/react-native": "^0.72.2",
    "@types/react-slick": "^0.23.10",
    "@typescript-eslint/eslint-plugin": "^6.2.0",
    "@typescript-eslint/parser": "^6.2.0",
    "babel-plugin-module-resolver": "^5.0.0",
    "eslint": "^8.45.0",
    "eslint-plugin-react": "^7.33.0",
    "eslint-plugin-react-native": "^4.0.0",
    "react-native-svg-transformer": "^1.0.0",
    "typescript": "^5.1.3"
  }
}

https://github.com/facebook/react-native/assets/99968085/0a278c22-2a67-4da4-844c-cd40f8445b29

v.0.72.4 app package.json fps around 8-30:

{
  "dependencies": {
    "@expo-google-fonts/inter": "^0.2.3",
    "@gorhom/bottom-sheet": "^5.0.0-alpha.3",
    "@ptomasroos/react-native-multi-slider": "^2.2.2",
    "@react-native-assets/slider": "^7.0.2",
    "@react-native-community/netinfo": "^9.4.1",
    "@react-native-picker/picker": "^2.4.10",
    "@react-navigation/stack": "^6.3.17",
    "@shopify/flash-list": "1.4.3",
    "@tanstack/react-query": "^4.33.0",
    "autosuggest-highlight": "^3.3.4",
    "axios": "^1.4.0",
    "compose-function": "^3.0.3",
    "dayjs": "^1.11.8",
    "expo": "^49.0.8",
    "expo-application": "~5.3.0",
    "expo-blur": "~12.4.1",
    "expo-camera": "~13.4.2",
    "expo-clipboard": "~4.3.0",
    "expo-constants": "~14.4.2",
    "expo-device": "^5.4.0",
    "expo-font": "~11.4.0",
    "expo-image": "~1.3.2",
    "expo-image-manipulator": "~11.3.0",
    "expo-image-picker": "~14.3.2",
    "expo-linear-gradient": "~12.3.0",
    "expo-linking": "~5.0.2",
    "expo-router": "^2.0.4",
    "expo-sharing": "~11.5.0",
    "expo-splash-screen": "~0.20.4",
    "expo-status-bar": "~1.6.0",
    "js-cookie": "^3.0.5",
    "moti": "^0.25.3",
    "patch-package": "^7.0.0",
    "postinstall-postinstall": "^2.1.0",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-hook-form": "^7.45.4",
    "react-imask": "^7.1.3",
    "react-native": "0.72.4",
    "react-native-collapsible": "^1.6.1",
    "react-native-collapsible-tab-view": "^6.1.4",
    "react-native-date-picker": "^4.2.13",
    "react-native-gesture-handler": "~2.12.0",
    "react-native-image-viewing": "^0.2.2",
    "react-native-keyboard-controller": "^1.6.0",
    "react-native-mmkv": "^2.10.0",
    "react-native-modal": "^13.0.1",
    "react-native-pager-view": "6.2.0",
    "react-native-ratings": "^8.1.0",
    "react-native-reanimated": "^3.4.2",
    "react-native-reanimated-carousel": "^3.5.1",
    "react-native-safe-area-context": "^4.7.1",
    "react-native-screens": "^3.24.0",
    "react-native-share": "^9.2.3",
    "react-native-svg": "^13.13.0",
    "react-native-tab-view": "^3.5.2",
    "react-native-text-input-mask": "^3.2.0",
    "react-native-toast-message": "^2.1.6",
    "react-native-web": "^0.19.7",
    "react-native-webview": "^13.2.3",
    "react-slick": "^0.29.0",
    "slick-carousel": "^1.8.1",
    "zustand": "^4.3.8"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0",
    "@babel/plugin-proposal-export-namespace-from": "^7.18.9",
    "@types/autosuggest-highlight": "^3.2.0",
    "@types/compose-function": "^0.0.30",
    "@types/js-cookie": "^3.0.3",
    "@types/react": "~18.2.14",
    "@types/react-native": "^0.72.2",
    "@types/react-slick": "^0.23.10",
    "@typescript-eslint/eslint-plugin": "^6.2.0",
    "@typescript-eslint/parser": "^6.2.0",
    "babel-plugin-module-resolver": "^5.0.0",
    "eslint": "^8.45.0",
    "eslint-plugin-react": "^7.33.0",
    "eslint-plugin-react-native": "^4.0.0",
    "react-native-svg-transformer": "^1.0.0",
    "typescript": "^5.1.3"
  }
}

https://github.com/facebook/react-native/assets/99968085/3ba1642e-c330-4339-ac05-c8f2ae27d6f2

Kudo commented 1 year ago

@devoren the is a unfortunate for jsc. do you have ??= in your code?

devoren commented 1 year ago

@Kudo nope, i dont have any ??= in my code, only in node_modules

Kudo commented 1 year ago

@devoren what if to manually change the ??= in the node_modules? appreciated for your help again!

cipolleschi commented 1 year ago

Hi there, Nicola is out and he will be back on Monday. I'd like to summarize the status of this issue to make it easier to jump on this. Please let me know if this Summary is correct. Specifically:


Summary

What's the Effect of this issue:

Platform affected:

Version Affected:

JS Engine:

Repro link:


SirCameron commented 1 year ago

@cipolleschi I've tried with hermes=false on Android, RN 0.72.3... still as slow as with Hermes.

devoren commented 1 year ago

@Kudo I changed all logical assignment operators in both versions and tried it, it works. But the performance has not changed at all, and maybe worse than Hermes :( @cipolleschi changing engine did not help

Edit: One thing I've noticed is that in version 0.71.8 the frame rate stabilizes faster than in 0.72.4. I mean in version 0.71.8 fps: 40-45 -> 60 and stable. In version 0.72.4 fps: 10-30 -> 30-45 -> 20-40 -> 60. All tests were done in DEV mode.

diegolmello commented 1 year ago

@cipolleschi both iOS and Android

berdyshev commented 1 year ago

we had 0.71 with Hermes and jsc-intl enabled. we had performance issues for both ios and android. once we downgraded to 0.69, disabled Hermes, and rolled back to just jsc — the app became much-much faster. and each of these steps has its effect on performance.

PrakashkumarM commented 1 year ago

Recently, we encountered performance issue when using React Native version 0.71.8. To mitigate this problem, we made the decision to downgrade our app's React Native version to 0.68.7 temporarily. Now performance was too good.

And nativebase latest version also impacted our app's performance. we're try to remove the nativebase elements from our app.

Kudo commented 1 year ago

@devoren awesome! pretty appreciated for checking that. trying to conclude a little bit for performance drop when 0.71 -> 0.72

devoren commented 1 year ago

@Kudo Is a simple hello world module enough, or is a complex module needed?

aweffr commented 1 year ago

Any updates on this from core team? The best solution for now to workaround performance issue it to rollback to 0.68.x?

Kudo commented 1 year ago

created a simple example to compare native modules performance between 0.71 and 0.72: https://github.com/Kudo/rn-native-module-perf

result as following. it looks like no significant native modules performance difference between 0.71 and 0.72. the performance regression might come from uimanager?

version result
ios 0.72 (old arch / bridge) 180.186
ios 0.71 (old arch / bridge) 181.240
ios 0.72 (new arch, turbo module, based on jsi) 121.885
ios 0.71 (new arch, turbo module, based on jsi) 136.654
android 0.72 (old arch / bridge) 851.222
android 0.71 (old arch / bridge) 840.937
android 0.72 (new arch, turbo module, based on jsi) 731.056
android 0.71 (new arch, turbo module, based on jsi) 726.573

Profiling details:

andac-ozcan commented 1 year ago

Here is another test that compares 0.70.8 and 0.72.4 by using Android release builds. I ran the same detox test 5 times on API-31 Emulator, logging in and then scrolling in the same content-rich screen(flatlist) with rendering same data. The test takes ~30 seconds. I used Flashlight to measure performance. Test duration should indicate little due to backend/network performance differences. However, memory and CPU usage are helpful to project differences. Based on the results, I saw little difference between 70 and 72. Only JSC performance looks a little degraded and uses more memory than Hermes, which is expected. Unfortunately, I cannot share a repo for these tests.

Screenshot 2023-09-05 at 15 35 45 Screenshot 2023-09-05 at 15 46 17 Screenshot 2023-09-05 at 15 42 12
diegolmello commented 1 year ago

@Kudo @andac-ozcan This issue is mostly related to a regression from 0.69 to 0.70+ https://github.com/facebook/react-native/issues/36296#issuecomment-1701206097

0.72 is an improvement in comparison to 0.70 and 0.71, but it's still not as performant as 0.69. Have you seen this?

Kudo commented 1 year ago

0.72 is an improvement in comparison to 0.70 and 0.71, but it's still not as performant as 0.69. Have you seen this?

@diegolmello yep i saw these great repro. when went through the whole issue thread, i feel confused, especially when some people said 0.72 is better and the other people said 0.72 is worst. trying to investigate one thing at a time, for me, i would like to check the regression from 0.71 -> 0.72 that @ajsmth and @devoren encountered first. (https://github.com/facebook/react-native/issues/36296#issuecomment-1663132701 and https://github.com/facebook/react-native/issues/36296#issuecomment-1701066903).

AndreiCalazans commented 1 year ago

These finds could be red herrings to the actual problem, but anayzing the JavaScript CPU profilings of latest main (92d84286448b8c9de3f17a27f8169e99a91ba725) with 0.68.7 a few things stood out to me.

I welcome you to download the zipped CPU proflings. There are three profilings of each version - latest main and 0.68.7.

The profling consists of me using the rn-tester app with the animations @tj-mc shared on a low end Samsung A31 phone with DEV false and performance monitor enabled. See the video below of how each version looks:

0.68.x: https://github.com/facebook/react-native/assets/20777666/58fc61d8-e9d3-406e-b054-e1ca5960aad6

main 92d84286448b8c9de3f17a27f8169e99a91ba725: https://github.com/facebook/react-native/assets/20777666/9610392e-1cf3-4830-be50-be634e88dcaf

What to look for in the above video?

Profile files

Profilings 0.68.7.zip

Profilings latest main.zip

Notes about the profilings:

Observations From CPU Profilings:

Doubled cost of renderWithHooks

The total time spent in renderWithHooks doubled between these two versions. The profilings seem to point to useAnimatedProps' getValue call.

https://github.com/facebook/react-native/blob/d468d9d57f1c6973c7bbadaecfcd61c173716b02/packages/react-native/Libraries/Animated/useAnimatedProps.js#L125

renderWithHooks profling screenshot of latest main:

image

renderWithHooks profling screenshot of 0.68:

image

arrayPrototypeIndexOf

Native calls seem to be a bit slower too. [Native] arrayPrototypeIndexOf for instance is much slower in latest main.

0.68.x: profiling on 0.68.8 of native arrayPrototypeIndexOf

latest main:

latest main profiling of native arrayProtypeIndexOf

Time Spent In queueOperation

Could be a change in architecture, unsure, but time spent in queueOperation sky rocketed in latest main in comparison to 0.68.x:

queueOperation in 0.68.x

queueOperation in latest main:

diegolmello commented 1 year ago

Awesome, @AndreiCalazans! Can you do the same for 0.70 and 0.71? I think one those introduced this regression.

brentvatne commented 1 year ago

@AndreiCalazans - in addition to what @diegolmello requested, would you be able to provide a link to your repo on github?

AndreiCalazans commented 1 year ago

Will do @brentvatne @diegolmello .

I'm not fully confident with my measurement method, so instead I want to use Flashlight to get FPS and memory metrics of each version and see if that also proves that there are FPS performance regressions between these versions.

The cpu profilings are bit too wide scoped and hard to derive any information from. For instance I profiled 0.70.0 and found it didn't have the doubled renderWithHooks total times that latest main did which means that observation is not causing the low values in FPS for that animation.

@brentvatne as for a reproducible repo, I'm using the rn-tester app in RN Core repo. I'm simply replacing the RNTesterShartedApp.js code for the animation TJ provided: https://gist.github.com/AndreiCalazans/41a4a82bb9aa010d83ba3e9cfe2ce81c

If Flashlight is capable of detecting FPS regressions between these versions I can try to git bisect what commit caused it, but bare with me as this is a very slow process to do due to the requirement of rebuilding Android.

I'm only looking into Android.

AndreiCalazans commented 1 year ago

We are still building a case here to try to understand where to look at next. Solely based on this animation example ran using the rn-tester app on a Samsung a32 device with DEV mode FALSE we can say there is an FPS regression between 0.69.x and 0.70.x.

Note that on latest main (92d84286448) there are improvements in comparison to 0.71.x but we are still hitting very low FPS (values below 5).

Screenshot 2023-09-07 at 18 06 23

0.68.7 had the best minimum FPS

Screenshot 2023-09-07 at 18 04 20

0.68.x and 0.69.x were very consistent with each other indicating regression started in 0.70.x, the difference here consists mostly of when I pressed the mount button:

Screenshot 2023-09-07 at 18 05 33

There might be another issue after 0.71.x. On latest main FPS does not stabilize as it does on previous versions.

image

What to look at in this chart:

The JavaScript Profilings:

Using npx react-native hermes-profiler I retrieved the following cpu profilings of each version.

javascript cpu profiles.zip

I welcome help analyzing these but I found that analyzying the cpu profilings to be a bit misleading since something might have regressed in total function call times but might not caused FPS degradation as I saw with renderWithHooks total time comparison between 0.70 and 0.69.

FlashLight Reports

To see the report install Flashlight then use flashlight report <file name.json>:

flashlight report 0\ 68\ flashlist.json 0\ 69\ flashlight\ profiling.json 0\ 70\ flashlight\ profiling.json 0\ 71\ flashlight.json latest\ main\ flashlight.json flashlight reports.zip

What's next?

I will git bisect all changes between 0.69.7 and 0.70.x to see which commit regressed the initial FPS on render.

The CPU profiles I shared here could help investigate re-rendering cost although I'm not entirely sure I know how.

matt-42 commented 1 year ago

Which JavaScript engine engine did you use on each of those version? 0.70 was the first to use Hermes by default. Maybe benchmarking 0.70 with JSC and 0.70 with Hermes could give some insight whether or not this framedrop is due to the engine switch or not.

AndreiCalazans commented 1 year ago

@matt-42 I've been only testing with Hermes enabled and without Fabric.

cortinico commented 1 year ago

Hey all, Nicola from the React Native team,

I'd like to share a short update here: we're still actively investigating this issue.

First thanks for the reproducer that got shared, that was really helpful in understanding what was going on. At the time of writing, I was able to notice a drop in FPS from version 0.69 to 0.70 that I'd like to investigate further. The issue seems to be related to a React <-> React Native interaction.

We'll share more information in the near future as I continue investigating.