To React Native or to Not React Native, That is the Question
We took React Native for a test drive - here’s what we came up with.
When you’ve done mobile development for a long time, it’s pretty easy to overlook the quality and effectiveness of your processes and development. From time to time, it’s good to take a step back and look at how you do things.
Like any other company, we at Showmax always think about efficiency with our development projects - we don’t want to waste time and money on things that don’t work. More importantly, we care about the future and we’re thinking about it all the time. In this case, I want to talk about scaling a business.
We want to be prepared for Showmax’s growth, and that means looking at how we do things now, how we’ll do them when we have twice as many customers, and then five times as many, and so on (fingers crossed!). There are basically two ways to expand a development team - hire more developers or find them internally. But, what about cross-platform development? What can it bring us? What would it cost? What are the pros and cons?
React Native (RN) is definitely not the only cross platform framework available, but it has the largest community and resources behind it, so it wasn’t a difficult choice. It was also great, because our teams had no experience with RN or JavaScript.
Mission Accepted & First Impressions
Obviously the first goal was to look under the hood and get to an understanding of the basics. It was fun, and took us just a few hours to start getting some results. It was an amazing experience to see how quickly you can get into it, and how a lack of JavaScript and React experience wasn’t a problem at all. Even wrapping our own native code was done when we were basically still looking around and learning.
Our mission was to literally break it - we wanted to find issues, cracks, bottlenecks, anything that could slow us down.
Learning the basics of RN is pretty easy, but the fun kicks in when you’re looking for some juicy and advanced stuff. The documentation is quite good, but it’s not advanced at all, so when you need more, you have to ask the community or Google it. One downside is that there are a lot of obsolete articles and tutorials about RN - so Google with caution.
Over the Bridge
Every system has its own Achilles’ heel, and we noticed very quickly that for RN it could be a communication bridge connecting JavaScript to the native part of the app. JavaScript runs in a webcore that runs as a separate thread in the native app. It’s not a UI thread that helps the UI and interaction with the app. It acts as the only connector between those two worlds, so it’s a good candidate for failure.
First, the amount of data traveling from one side to other side and back should be as low possible. What does “low” mean? It depends on the use case, so we decided to define a proof-of-concept app that would suit our needs. The app we built was a two-screen app with a grid of movie posters with vertical scrolling and lazy loading. Our goal was to measure the amount of data we could pass through the bridge, and then evaluate the result. Our assumption was that the bridge would fail - but we were wrong. If you use the bridge in a common-sense way, the data could be pretty big. 6KB of assets data in our case was just fine. Here’s why:
- All communication over the bridge is asynchronous
- JavaScript creates a virtual DOM that takes care of updating just the necessary parts of the UI - ones that changed state
Just like reactive programming forces you to think differently, sending data over the bridge needs the same. You don’t want to send the whole image through the bridge when you can send just the URL and let JavaScript do the rest. Be reasonable, design the structure of your data and flow carefully, and you should be fine just like we were.
Reasons Not to Proceed with RN
Our goal was to answer a “simple” question - should we move forward with RN? Our early success was great. Android developer Jakub Broz was working on two screens for just two days, and iOS developer Michal Fousek had everything working basically out-of-the-box. We certainly saw the potential of cross-platform development.
However, our standards are very high in terms of both development processes and their end results. There were some roadblocks we found to be too important, and we decided to not proceed with RN. Here are some of the issues we had:
Poor Components
Our app is mostly table- or grid-based, so users scroll a lot through dozens of items. RN provides FlatList, which is fine for basic usage and a reasonable amount (a few dozen) of items. Unfortunately, FlatList doesn’t provide the same feature set and performance as native components like RecyclerView on Android and UITableView/UICollectionView on iOS. We tried to use multiple 3rd party components that claimed to be able to handle scrolling through hundreds and thousands of items, but none of them worked well enough.
Poor Navigation
RN provides its own navigation which, unfortunately, is not based on native navigation in either iOS or Android. It’s just a stack of components/views with some basic transitions. It doesn’t look good, feel smooth, nor is it what the user is used to. Wix implemented a package of navigation that runs natively on both iOS and Android, but it’s only focused on mobile devices, and we were looking for native navigation even for tvOS and Android TV. Therefore, Wix’s solution didn’t solve our needs either.
Mobile Devices Over Leanback
Generally, there is better support for mobile devices compared to TVs, but Android TV is not supported at all. A recent pull request has added support for Android TV, but it is still missing any focus handling, so developers have to do it by themselves. On tvOS the focus engine is presented, but it’s missing native navigation.
Debugging
The ability to debug a developer’s issue is, without question, the most important thing. Unfortunately, the Android debugger has some serious issues with attaching to the app - for us, it worked one or two times out of ten. It’s worth noting that the iOS debugger worked absolutely fine.
iOS Over Android
It’s not a surprise that development for iOS is a bit easier compared to Android, even in native form. Android systems, the various devices and models, and dozens of screen resolutions, have always made things more challenging for Android developers. The same is true for RN, it just looks like iOS is more supported. Android developers should prepare for more complications than their colleagues working in iOS.
Write Once, Run Everywhere
Usually, cross-platform development means, “write once, run everywhere.” This is not a case with RN. It’s more like, “learn once, write anywhere” - a totally different experience with totally different consequences. Thanks to a reactive programming approach, JavaScript, and the logic of RN, once you learn it you can jump even on web or smart TV development and use tools like React.js (for example). It’s important to understand that writing just one code base and hoping for it to run on the smart TV, web, iOS, Android, and leanback, won’t work. There are differences and they have to be handled case-by-case. On the other hand staying just on mobile devices would work well.
Maybe in the Future: v1.0
It’s important to note that RN is still under heavy development and pretty far from being a stable and production-ready version. Version 0.55 (up-to-date as of this writing) gives us a clear vision of where they are at the moment. Also, the development of all native systems is pretty fast, but RN is still in catch-up and remains a few steps behind. A perfect example is the iPhone X - which you either have to wait for, or implement support for it on your own. Imagine how many devices and changes both Apple and Google do every year.
Lack of Experience
There is no best principle for how to build an app, and it’s easy to think of several concepts and architectures for how data will flow through it, interactions, and navigation. You can do a lot on just the JavaScript side, or do everything natively and just build the UI with RN. You can implement custom modules or create a whole new set of components, even advanced ones. What’s right or best is not always clear and obvious - it takes research. For the best results, using RN is definitely not fast, and building a custom module and component such as Wix’s navigation will take a lot of time.
Hybrid Over Fully RN
After quite a bit of experimentation, we realized that, in order to build a great app that would fulfil our expectations, hybrid was a better choice. Whenever there is a screen or logic on which users depend, it’s better to do it natively. All other and less-frequently used parts of the app can be switched to the RN version. We believe that even Facebook (author of RN) has actually done it this way.
Using RN for prototyping is still a good choice - it’s amazing how fast you can build a working app. We also like the instant reload and update of the simulator when you do a small change in the code.
Conclusion
We like RN so far, but we don’t believe it’s ready for bigger businesses at the moment. It can still be used for prototyping and internal app development though, and we’d actually recommend it for just that purpose.
In our case, we can’t have a framework that we fight with next to day-to-day issues. We tried it out, learned a bit, finished our proof-of-concept, and decided to get back to RN in few months to check out their progress. At some point, we’re sure it will be ready. When that day comes, we will seriously consider using it.
Have you worked with React Native? Do you agree or disagree with our findings? We’re always looking for sharp minds and good ideas, and would love to hear from you. Find us on Twitter or drop us an email, and let’s solve some problems together!