We are trying to use React Native to rebuild the whole app, so that it can be run on iOS and Android with the same code base at the same time. I have been working on this with my teammates for a few weeks, and I would like to share some of my thoughts.
I have to admitted that it’s quite attractive, as you can use the same code base to make an app that runs on iOS and Android.
However, as we keep working on this, we found out that many places require us to perform native bridges, that is, writing Java and Objective-C for Android and iOS respectively due to performance issue or some of the libraries that we are using, doesn’t support React Native out of the box.
Native code for performance
Our app contains many long images, due to performance issue, we cannot load the whole image into memory, we just load what can be seen on the screen to optimize memory usage. Since we have already written this widget in native code, all we need to do is to write a JS interface to bridge the native code. Moreover, there were also some UI glitches when using native views with React Native that take us some time to fix.
Native code for existing libraries/SDK
Yes, there are quite a number of people wrote native bridges for some popular SDKs or libraries. e.g. Google sign in. However, not all of them suits our use case and requirements, we have to fork out the project and make some of our customization in it. Some lower level handling like file system, push notification, download require native bridges. Yes, these libraries are great already but for example, the push notification library itself doesn’t support showing BigPictureStyle on Android yet. Therefore, we have to fork the original project and write our native code (We can contribute back to the project later :D). Some others like crash reporting tools, Ads SDK… Our project consists of more and more native modules, it’s like defeating the purpose of using React Native.
This is the part that we concern most. The original app on Android was using about 10–30 MB of heap, however the React Native version, is using about 60–70MB of heap, which is more than a double. Besides, our app heavily use the list view. However, the ListView implementation of React Native is a like a scroll view, where it append view items to the list, no reuse mechanism so far. Even there’s a RecyclerViewBackedScrollView, but if you look at the source code, there isn’t any view reuse at all. The app performance must gradually degrade as the time spending on the app increase. Though some people tried to optimize the performance of the default ListView, but we are reluctant to use it as the project is not very active and we know that React Native is releasing frequently, we don’t know when it will break the API. Here’s a talk about how to optimize the performance of React Native, however, the systrace tool is available on iOS only at the moment. Even Airbnb’s engineer said that they don’t use React Native on all parts of their Android apps due to performance issue.
We are using Nuclide, which is the official recommended IDE. However, we found that the find reference feature is quite weak when comparing with WebStorm, so some of our teammates has paid for it for better development experience.
In my opinion, React Native is still young and evolving, it has a great potential. It’s a great framework for fast prototyping and proof of concept. It’s also great for web engineer to participate in mobile app development. They can pick it up very quickly.
However, if you are talking about more complex usage like us, or performance is your big concern, then you have to think carefully before you move on to this framework. Otherwise, you will need to write lots of native bridges, spending time on tuning the app, which may slow down the development process.
We hope Facebook could make this framework better and better so that it’s really close to native experience. What’s your thought? Or do you have any experience to share? Feel free to comment! :)