The Final Call — The good and the bad of React Native

The Final Call — The good and the bad of React Native at Grofers Taking a look at all that’s good and bad with the brownfield integration of React Native into the Grofers apps and how we are dealing with it Photo by Tingey Injury Law Firm on Unsplash This blog is part of the Grofers React Native blog series. […]

The Final Call — The good and the bad of React Native at Grofers

Taking a look at all that’s good and bad with the brownfield integration of React Native into the Grofers apps and how we are dealing with it

Photo by Tingey Injury Law Firm on Unsplash

This blog is part of the Grofers React Native blog series. Through this series we attempt to share the journey of integrating React Native into one of India’s largest e-commerce grocery’s web & mobile apps

It’s been almost two years since we at Grofers started integrating React Native into ourapps & website. In these two years, we have managed to handle all the business requirements while maintaining brownfield apps across platforms with a very small and lean team.

▹ The first year involved a React-Native POC with just a UI widget. It was then followed by porting our homescreen and all widgetised pages covering most of our marketing pages.

▹ The next year involved migrating our post-checkout flow (thank you screen, order details) and the browsing flow (product details and listing pages).

At present, apart from checkout workflow screens, all our screens are now migrated to React Native.

So, in total we are now roughly 80% React-Native.

PS: We also managed to give our apps a complete new look and change navigation while doing the migration.

Here’s a quick look at all the goods and not-so-goods of React Native that we have experienced.

The goods 😇

▹ Feature parity across all platforms — Android, iOS, mobile web & desktop web

▹ Better development experience compared to native

The far fetched goods 😤

▹ Faster multi-platform development (coding in 1 platform instead of 4). Status: 5/10 ⚠️

▹ Faster release cycle & adoption with OTA (Over the air releases). Status: 5/10 ⚠️

(Read below for more details on how we are going to be achieving these)

The bads 😒

▹ Extra effort in maintaining high performance

Let’s dive into details of each of these one by one:

The goods 😇

Feature parity across all platforms

Status: 10/10 

Earlier there were many features that used to get reported on our primary platform Android and then other platforms always played catchup mode.

What got achieved:

1. Widgetised Screens across platforms

▹ Features like widgetised (or backend driven) framework for screens got ported to iOS & Web as well. Thanks to React Native, it has now enabled all tech and non-tech teams to create new layouts on the fly across all platforms.

2. Cross-platform feature parity

▹ Lots of other features which only had got ported into Android like our listing page filters, etc. are now ported across all platforms.

▹ All our analytics events and impressions are also at parity across platforms.

▹ No more platform specific bugs being reported like our membership widget not shown correctly in iOS which were earlier not considered to be done on iOS by backend devs or product teams.

3. Quick to roll out bug fixes across platforms

▹ For example, a very small change request from compliance team to change MRP text on our product page from 25 to 25.0 was done unbelievably quickly. The change was made across platforms as developer had to make change just at a single place rather than involving chapter leads of 3 different technologies and asking multiple devs to accommodate the task in their sprint.

Better development experience compared to native

Status: 10/10 

What got achieved:

1. Live Reload

▹ The live reload feature of React Native is simply amazing and is absolutely loved by our Android developers. To see their changes load within a few seconds gives a much faster feedback loop to developers.

2. Live Reload 2.0

▹ React Native Live Reload feature got more love with the Fast Refresh feature after we upgraded to React Native(v0.61).

The far fetched goods 😤

Faster multi-platform development (coding in 1 platform instead of 4)

Status: 5/10 ⚠️

Coding in React Native generally takes much lesser time as compared to coding in all platforms separately. But still there are some questions to be answered before a dev can start coding in React Native.

What got achieved:

1. Dream of ONE Frontend team

▹ There’s now only one frontend team at Grofers rather than 3 (Android, iOS, Web) before. Though there are technology specific experts but almost all frontend developers can work fluently in React Native. This leads to better focus (3x more) to improve our React Native platform and also makes it quicker to form a new team and not having to figure out whether the team would need Android, iOS or Web developer.

Still to be solved:

1. Frontend developers not testing changes across all platforms

▹ Frontend developers are still not used to testing their change across all platforms and it feels a lot of effort for them to locally test their changes across web & iOS. This can introduce platform specific bugs sometimes.

2. Decision making whether to code in React Native or go native

▹ Lots of decision making causes slowness in development. Which React Native library to use? Will it work for all platforms? Use any existing React Native library or make a native module for a functionality not yet supported? Will React Native be able to handle a new animation or should we resort to doing it in native?

How we are fixing:

1. Better CI tooling

▹ For developers to release their change confidently, we are now strengthening our continuous integration process. We have started integrating UI automation tests and Robo tests (using Firebase Test Labs) which would be running across platforms for multiple devices on every change request so that developers don’t have to worry about breaking anything across platforms.

2. Better Development Experience

▹ We are also improving development experience for web to make it easier for Android developers to test their changes in web. This involves having web as a mono repo rather than a submodule to make it easier to switch from React Native to web for anyone.

3. Extensive documentation

▹ To tackle all the complexities of React Native, we have documented a lot of flows like how navigation works in a brownfield app, etc. We have also written some extensive guides like React Native migration guides, React Native onboarding guide (for native developers new to the React Native world).

4. Strengthening the open source community

▹ Whatever code we develop or any repository we fork, we always construct it in such a way to have open-source in mind. React Native today is heavily reliant on third party libraries, and some that are not well maintained really slows down development. We are looking to open-source our cross-platform image carousel library (that works on web too) and our cross-platform storybook starter project.

Faster release cycle & adoption with OTA (Over The Air) releases

Status: 5/10 ⚠️

Using codepush, it’s as easy as running a command from CLI and we can take our code deployed to production (no more Google Playstore and Apple App Store reviews). But with more power comes more responsibility and this power can sometimes prove risky.

What got achieved:

1. Quickly deploying changes during sale

▹ Since there are numerous new requirements during our sale period, React Native has come as a blessing for us. Changes for our last GOBD (Grand Orange Bag Days) sale were made instantly live and reached 70% of users within a day of code merge as opposed to waiting for days of Playstore review and then waiting for users to update their app.

2. Seemless to deploy bugfixes

▹ All our small changes and bugfixes are now deployed with instant reach across platforms and without much effort.

Still to be solved:

1. Low confidence in deploying bigger changes

▹ The problem comes with bigger changes. Now to be able to release quickly, developers need to have more confidence on their change. But still developers are sometimes relying on manual QA for doing any OTA release.

2. Dependency on manual testing

▹ With dependency on manual testing for new features, we are not be able to achieve our dream of releasing frontend code within an hour.

3. Lower release adoption with every native side dependency

▹ For every change that involve native side dependency, we end up putting a check on the minimum version of the app that our React Native bundle can target. This reduces our OTA reach from 90% to sometimes only 60%.

How we are fixing:

1. Building more confidence in OTA releases

▹ We are extensively working on increasing our code coverage by writing automated tests for our business flows involving HOCs. We are training developers to get better in doing Test driven development to be able to do OTA releases quickly without relying on manual testing.

2. Faster & reliable E2E testing

▹ We are also exploring cross-platform gray box E2E testing options like Detox which will enable developers to write E2E tests within their React Native codebase to have much better control. Selenium / Appium black box testing setups are proving to be less reliable, more time consuming and difficult for developers to maintain.

3. Increasing adoption by adding fallbacks for older versions

▹ For increasing our OTA codepush bundle reach to more users, we now provide some fallback in case user is on older app which doesn’t support a required native module or native UI component.

For example, recently for a feature request to make images turn grey scale when the product goes out of stock, we safely checked on the RN side that if the native dependency is not found, we fallback to showing normal colored image rather than than putting a minimum version check on our React Native bundle.

The bads 😒

Extra effort in maintaining high performance

Status: 7/10 ⚠️

For simple use cases, React Native has been working pretty well for us. But as we move into more & more advance use-cases, we are realising that getting to optimal performance takes some effort and time.

For instance, we had to fork and fix the tab switching library that we used for switching tabs on our listing pages as it made heavy use of react-native-reanimated library, which was flooding the infamous RN bridge with all the predefined animated nodes being set on native side.

Still to be solved:

1. Large lists performance

▹ We are still seeing issues with rendering long lists (like homepage) in iOS which becomes laggy especially when we have many heavy widgets like GIFs. The recycling doesn’t perform as well as native would.

How we are fixing:

1. Waiting for changes from React Native Core

▹ We are hoping that with React Native’s JSI interface and all the other advances, lot more performant libraries will come up without the dependency on bridging.

2. Careful integration of React Native libraries

▹ We always keep a check on any new library that we integrate and test it thoroughly before integrating.

3. React profiling for re-rendering

▹ We are always careful of not doing unnecessary re-renderings as that can impact app’s performance big time. We are making use of why-did-you-render for that.

Final Verdict ✌🏻✌🏻✌🏻

We’ve heard stories of Airbnb & Dropbox who realised the pains of working with cross platform technologies. We are now hearing success stories of Shopify & Coinbase who have managed to complete their React Native migrations successfully.

This is our story.

Porting to React Native was a bold move from us and maintaining the performance required a lot of in-depth understanding of the React Native and the Native world.

Overall, with every challenges that we see and fix, we are getting more and more confidence on our move to React Native.

Major advantage that we are seeing is singular focus of the frontend team and flexibility in forming small teams and do experiments at will.

This singular focus and single platform frontend team also brings in a lot of platform optimisations that we are able to do together like creating an offline-first experience for customers.

We get 3X more brains to solve both technical and customer problems when we combine all frontend teams into one.

So far, we have managed to keep up with both performance and stability and we are getting good speed of execution on feature development even though migrations did slow us down a bit.

We are sure, as the team gains more expertise into React Native and we manage to fix all what’s left to be fixed as highlighted above, we are very soon going to utilise all the benefits that React Native has to offer.

We have a dream to chase — to continuously deploy every single change of frontend across platforms like we do in backend today. And we are pretty sure we are going to reach there soon !

Ashish is the Platform Frontend Lead at Grofers. Got questions or have suggestions? Reach out to him at [email protected].

Thanks for reading Lambda.

Say hello on Twitter or follow us on LinkedIn.

We’re hiring!

We are hiring across various frontend roles! If you are an expert native developer who has never done React-Native before, worry not as we have prepared a proper onboarding guide for you.

If you are interested in exploring working at Grofers, we’d love to hear from you. You can either apply on LinkedIn or directly reach out to the author on Twitter or LinkedIn.

The Final Call — The good and the bad of React Native was originally published in Lambda on Medium, where people are continuing the conversation by highlighting and responding to this story.

Source: Grofers