[0.76] Introducing libreactnative.so
- Reducing app size and improving startup time on Android
#816
Replies: 12 comments 15 replies
-
great work guys!! 👏 🔥 |
Beta Was this translation helpful? Give feedback.
-
super excited for the change 🤩 |
Beta Was this translation helpful? Give feedback.
-
Amazing guys 🤯🔥 |
Beta Was this translation helpful? Give feedback.
-
This is very clear communication. Thank you. |
Beta Was this translation helpful? Give feedback.
-
exciting 🔥 |
Beta Was this translation helpful? Give feedback.
-
Super excited for this🔥 |
Beta Was this translation helpful? Give feedback.
-
This is amazing! |
Beta Was this translation helpful? Give feedback.
-
Instead, we're using |
Beta Was this translation helpful? Give feedback.
-
Great. In an old project that uses android.mk to build SO files, is there a similar feature available for merging SO files? |
Beta Was this translation helpful? Give feedback.
-
Super excited for this! 🎉 The way you guys are making progress, by the time you hit 1.0 🚀, it’s going to be so much more stable! 💪 |
Beta Was this translation helpful? Give feedback.
-
Where can I find the namespaces names of the exposed ReactAndroid::libs? I depend on:
But it's not clear to me with what should I replace them? |
Beta Was this translation helpful? Give feedback.
-
I don't understand anything. I updated my application from 0.74.0 version to 0.76.0 and my application began to weigh 2 times more (it was 35mb, it became 79 mb) What went wrong, I don't understand. The old version - https://disk.yandex.ru/d/YpF1K_DXu1BstA Maybe they'll tell me what's the matter here? I just updated react-native and that's it. |
Beta Was this translation helpful? Give feedback.
-
tl;dr: React Native 0.76 will ship with a reduced number of dynamic libraries: this reduces app size, and improves performance. This is a breaking change if you’ve been writing C++ libraries for Android. This post is for advanced React Native developers. If you’re an app developer, this change will not affect you
React Native 0.76 for Android will ship with a dynamic library called
libreactnative.so
. This library merges the dynamic libraries we used to ship in previous versions and offers improvements in disk size and performance.Keep reading to learn more about this change and how you can adapt your Android/C++ libraries to comply with it.
Context
Historically, React Native for Android used to ship a long list of dynamic libraries (aka
.so
files). This was caused by our folder structure. On top of that, a lot of different libraries had aJNI_OnLoad
method that was causing several duplicate symbols.For example, an Android app with React Native 0.74 ships with 43 dynamic libraries:
In React Native 0.76, the list of dynamic libraries has been reduced to 10:
This was possible thanks to the introduction of Native Library Merging for React Native Android.
What’s the impact of this change
Native Library Merging is a feature that we use at Meta when shipping all of our Android apps. You can read more about it here: https://engineering.fb.com/2018/01/23/android/android-native-library-merging/
This feature was not available to React Native app users yet, due to limitations of the React Native build and SoLoader. In React Native 0.76, we were able to lift those limitations and ship Native Library Merging for everyone.
You will immediately see benefits in Android app size, with an empty app reducing by ~3.8MB (20%):
This will also benefit app startup time: we need to load fewer libraries, so your app will start faster.
Specifically between 0.75 and 0.76 we noticed a reduction of ~15ms (~8%) at median startup time:
_Benchmark methodology: Measures taken on a Pixel Fold (Android 14), averaging 10 runs, using the Android’s default Macro-benchmark test called
timeToInitialDisplayMs
(source).This change enables future optimization opportunities such as Link Time Optimization.
What has changed?
We merged a lot of the internal React Native C++ libraries inside a single dynamic library called
libreactnative.so
. This library is accessible via prefab in your CMakeLists.txt file with the selectorReactAndroid::reactnative
and all the headers that were previously available in the other libraries are still available.We also refactored the other dynamic libraries for JS engines:
libhermes.so
is the Hermes Enginelibhermestooling.so
contains all the tooling needed when running Hermeslibjsc.so
is the JSC Enginelibjsctooling.so
contains all the tooling needed when running JSCThose libraries are selectively removed from the final APK whether you’re using Hermes or JSC, to save space in the final APK.
The dependency of those dynamic modules looks as follows:
We’re also exposing
libjsi.so
as a separate dynamic library for advanced users to consume asReactAndroid::jsi
How am I affected?
This is a breaking change for library users writing C++ code.
If you’re not writing custom C++ code, you won’t be affected by this change at all.
Here's a (non-exhaustive) list of some popular libraries that will need to update. We'll work with them in the coming months to make sure those libraries won’t break in React Native 0.76:
If you’re affected by this change, your Android build will start failing in 0.76 with an error message similar to this one:
You can migrate your library already today to support this change in 0.76 (you don't need to wait for the 76 release).
The suggested change needs to be applied in your library’s
CMakeLists.txt file
and looks like the following.Beta Was this translation helpful? Give feedback.
All reactions