• Hemförsäkring
  • Skydd & villkor
  • Vanliga frågor
  • Om Hedvig
  • Skaffa Hedvig
  • Blogg
  • Going Clear: React Native...

Going Clear: React Native and the Prison of Cross-platform

Oscar Nylander
07 januari 2019
Oscar Nylander

Here at Hedvig React Native is a cornerstone of our frontend, given that our mobile application is the primary means of delivering our service (Home Insurance). One of the values our company holds dear is Remarkable Experience: we actively strive towards providing all of our members with a truly Remarkable Experience in insurance, an industry that traditionally has been filled with truly unremarkable or even downright frustrating experiences. React Native has steadily been increasing in popularity, most likely piggybacking on the success of React Web. We at Hedvig are big fans of React Web and the style of programming it brings: we are using React for all things web and have no particular plans of leaving it behind. React Native is, however, unfortunately a different story.

The usual arguments for using React Native

JavaScript

There is undeniably a lot of JavaScript developers on the market due to the web being one of the primary ways we deliver software to end-users. Being able to tap into this pool of developers is a lucrative prospect indeed.

Native elements

This factor is lucrative for anyone who has been working anywhere near any project attempting to create mobile applications using cross-platform frameworks based on Web technologies, such as Cordova. It's well known that these applications tend to 'feel' poor, owing to the fact that they are just simply web pages loosely encapsulated in a thin application shell.

Cross-platform

One code base for two platforms? Sounds a lot like there's money to be saved here, right? 🤑

Shorter development cycles

Again, we only need one codebase! 🤑

Continuous Delivery potential

With JavaScript, you can just push out a new bundle and your app is now suddenly right in the hands of all of your users. Instant delivery has been great on Web, right? Business people and developers love it alike.

Better developer experience

Hot Reloading? Say no more! After all, this is why doing web dev is such a nice experience these days, no?

Why React Native falls short, in our view

Is JavaScript even a benefit?

You will be paying a performance hit for this. In many cases, this does not matter, but it can, just like in the case of web-based mobile applications, translate to a poor experience in the form of various stutters, dropped frames and ruined animations. This may not be a dealbreaker for you, but if you are interested in delivering a remarkable experience, it very well might. There is also always the issue of the Native bridge, which is the glue that connects your JavaScript to the world of Native code. Merely using this bridge comes with a significant performance cost, and there's also the architectural issue that this bridge is entirely asynchronous (everything is a promise, period). The Fabric re-architecture will hopefully do a little bit to remedy this issue - fingers crossed. The Native bridge also imposes the very significant limitation that you cannot in a practical manner animate any layout property you'd like. Instead, you're stuck with the Animated-API with useNativeDriver. If you're not doing anything to the slim subset of properties Animateds native drivers can manage you're going to be stuck performing the animation from JavaScript which is, as you can imagine, dreadfully slow (ie unfit for animations which need to run at 60 fps).

Filled to the brim with obscure bugs

We use Sentry to track issues that may occur in our application in order to make sure that the experience we provide to our user is smooth and issue-free. Allow me to share a typical Sentry issue that we would get from our React Native-application:

EXC_BAD_ACCESS hash > isEqual: > moduleMapping > stringWithFormat: > Attempted to dereference garbage pointer 0x20a800000000.

The issues are not particularly easy to decipher and do require a fair bit of digging into the internals of React Native. I've never had to spend so much time code browsing until I started using React Native.

Libraries are of generally poor quality

Possibly owing to the fact that React Native is relatively young, possibly owing to the large share of mostly-JavaScript only developers, the available libraries in React Native are generally of pretty poor quality. This has lead us to have to fork a large number of libraries. The benefit of libraries becomes kind of negated if you're constantly forced to fork the libraries, learn the code and finally fix the issues present in the code. It is, of course, nice to be able to contribute back to the open source community, something we're big believers in, but when more time is spent in making the libraries work than creating a remarkable experience for our users, something is simply wrong.

Developer experience isn't even really any better

React Native touts an improved developer experience, with all the familiar techniques from web development, such as Hot Reloading. Hot Reloading is a fantastic feature, BUT, on React Native it really does not work as good as you would hope. I find myself being frequently forced to reload the entire application anyways (the classic Cmd-R on iOS or R-R on Android).

Continuous Delivery for apps is a hassle

Continuous Delivery for apps is something that seems extremely lucrative when coming from the background of Web development, and it is undeniably a cool feature. Missed a bug? You can just push out an update and your users won't even have to update their application! This only works until you want to update any of your native dependencies, in which case you lose the ability to push out new javascript bundles, as your bundles must always be compatible with whatever native code happens to be running in your application. Any upgrade to these means you're out of luck. There's also the issue of code bundle updates being a little bit iffy when it comes to the App Store T&C's, in that you're technically not allowed to provide new functionality via code bundle updates, as Apple requires an App Store review whenever new functionality is introduced. Combine this with the fact that a large number of users have automatic updates enabled for their App Store/Play Store and this is largely a subject which we've found is not worthy of our time.

The curse of the lowest common denominator

It should be noted that the users of the different OSes (we support iOS and Android) have different expectations for how applications in their OS are supposed to behave. If you care about providing a good user experience this must be a part of your design process. React Native does not provide these things automatically - that would probably be impossible - and hence you will need to spend a large amount of time making sure that things behave properly in each platform. As this is generally a huge hassle, React Native applications have a tendency to move towards the lowest common denominator in user interfaces, leaving your application feeling less like a native application and more like what a cross-platform solution like Cordova feels like. Not quite as bad, but still not quite as good as your app could be.

This is what we've decided to do in response to these experiences:

Go full native

As we are very concerned with being able to provide the best possible experience to our users, we've decided to transition away from React Native. We will instead build all our new features fully natively. It was not a decision we made lightly - we are still a startup with limited resources - but we've reached the conclusion that we simply cannot deliver a truly remarkable experience if we stay with React Native. We also think that the time saved from being cross-platform is overstated given the large amount of time we spend trying to fight React Native and its ecosystem to actually deliver the things we want to be able to deliver to our users.

Get there via brownfield

Luckily, the navigation library that we use, react-native-navigation, provides us with an escape hatch. We can use the registerExternalComponent-method to gradually introduce fully native components into our applications, while not being forced to re-write the entire application for both platforms right away.

For what kind of projects would React Native be a good fit?

  • Bootstrapping startup – When you're in the very first stage of a startup and you've decided that you will deliver your service through a mobile application (make sure that this is actually the right thing to do first! It likely is not), React Native might help you shave off a few days of development that may just prove to be invaluable. React Native may be a good candidate here - just make sure that you get off the train in time until you've already built yourself into a corner.
  • You want the app-equivalent of a WordPress web page – If you want to shave off some of the cost of development you may want to choose React Native to build your application. Just please make sure that you understand that you will be paying the price later on in maintenance costs and it will definitely be at the expense of your users' experience with using your application. If you do not care about this, you may want to use React Native. Then again, if this is the case, why are you even building an application? Websites are way cheaper and can probably do whatever you need. As mentioned in the previous section, make sure that you actually are willing to create a mobile application - these things, like all software, cost a lot of money to make.
Föregående inlägg

Year in Hedvig 2018

It’s been a great year at Hedvig. But the best is yet to come.

Läs inlägget
Nästa inlägg

Hedvig ❤️ Benify

What’s better than really great insurance? Really great FREE insurance!

Läs inlägget