Peacock, NBCUniversal’s streaming app, was initially built with React Native (RN) but recently switched to native. We observed this migration in April 2023 — v4.5.13 for Android and v4.4.22 for iOS.
RN is a framework developed by Facebook that lets you create mobile apps for Android and iOS using JavaScript. Some of the reasons to use RN include:
- Reduced complexity of 1 codebase providing multiple apps
- Robust tooling set (Expo, Hermes, etc)
- Active and engaged developer community
Below we'll look at how Peacock was built with RN and what happened when it switched to native.
React Native Builds
Peacock's RN builds share several frameworks and js files across platforms, although with some differences. Below you can see Emerge's X-Ray for iOS and Android, showing how the apps are built.
In both platforms, imports include Yoga, a React Native UI framework, and folly, a C++ utility package used by React Native. There are also a handful of libraries for image handling, animations, text, and more. Despite this, the project wasn't apparently using React Native to render UI (more on this below). Of note, we see that Peacock was not using Hermes, a popular RN framework used to improve RN performance.
Switching to Native
Peacock switched to native in April. This let them rip out all React-related code, resulting in a 26% size decrease (-7.6 MB) on Android and 13% decrease (-12.6 MB) on iOS. Below is our X-Ray diff, showing how the apps changed between builds. The nodes in red were shrunk or completely removed:
From the X-ray views you can see that the majority of the files that were removed were either precompiled binaries (.framework, .so) or js files. React Native imported utilites can now be replaced by native functionality if needed.
For example, RCTAnimation → CoreAnimation, RCTImage → UIImage/CoreImage RCTText → UIKit/CoreText, etc. Those native libraries don't take up space of your app, since they are provided by system frameworks, resulting in size reductions.
Impact on App Launch
Android
Android Performance AnalysisAs observed in the report above, the Android app launch improved by roughly 18.2%. When switching to the base build (which used React Native), we can see the app takes ~400ms to initialize com.facebook.soLoader.init
, based on our benchmarks done on Pixel 3 running Android 12:
If we toggle the "invert" view, it shows that the functions taking the longest to run also happen to be the ones from Facebook:
These functions are completely removed when you switch to native as the libraries required for running React Native are no longer needed. So here's where they get back that precious launch time!
React Native vs. Native
Comparing hybrid frameworks (React Native, Flutter, Xamarin, etc.) with native ones is often a heated debate, as both sides have valid arguments. One of the main arguments in favor of RN is the ability to have a unified codebase, enabling multiple platforms to share code and potentially be more cost effective. On the native end, one of the strongest arguments is superior performance. React Native has come a long way and KPIs like launch time has been greatly improved by frameworks like Hermes, but native code will usually be more performant.
We heard from @nunovieira_dev, who previously worked at Peacock, and he shared that the UI was already native prior to these changes, as they were using React Native just to share the business logic. When they made these changes, they moved the business logic to JavaScriptCore (which basically consists of js files containing the business logic and runtime interpretation of those files using native code). However, they still intend to move away from this approach and implement 2 separate codebases, using native code for the business logic, as there are still performance issues with using JavaScriptCore.
TL;DR
When Peacock made the switch from React Native to Native, both iOS and Android saw a size decrease from removing a number of RN-related resources. We were also able to measure a significant app launch improvement for Android.
There are many good reasons to use React Native, from code reusability to community support, familiarity with js, ease of finding hires, etc. However, if the business app performance is paramount, native is usually superior, especially the more complex your app gets.