Native, hybrid and HTML5 – three years later

Back in 2013 I wrote a blog post (sorry, in Finnish only) about the different ways to implement a mobile application. The major options of app development have remained pretty much the same since then. They were and still are:

  • Mobile optimised web app - make a web app that works fluently in mobile if you don't need an app in the App Store or Google Play.
  • Native application - write the app in purely native code. iOS + Android equals roughly double the work. Best usability, best performance.
  • A hybrid or cross platform app - use some framework to utilise the same code for different platforms in your app. Saves development costs, but traditionally you need to prepare for compromises in performance and usability.

The first two items haven't seen any major revolutions during the last three years. Sure, almost every web site is designed also for mobile - or even mobile first - these days. And web technologies have seen the rise and fall of more web frontend development frameworks than there are wrinkles in an elephants scrotum. I suppose the queens of the frontend development anthill are Facebook's React and Google's AngularJs. Although, the latter is being obsoleted by Angular 2 as I write this.

One thing worth mentioning is Google's work with Progressive Web Apps. They promise a lot of features of a mobile app with the ease of linking, updates and discoverability of a web page.

Native apps are still native apps. Naturally, Apple and Google have been working hard to evolve their SDK's and are coming up with new features for developers to use constantly.

The problems with webview

So what is it about the HTML5 hybrid apps that makes the performance and usability so much worse than native? In short, they are based in web technologies and wrapped into apps with tools such as Phonegap. Basically they take the Javascript/HTML5/CSS code, create a an internal web browser (webview) inside a native app frame. This means that all the code is ran in Javascript, which the browser interprets and then renders into UI that the user can interact with. Even as the Javascript performance of mobile browsers has constantly increased, a lot of devices have trouble reaching a silky smooth 60fps.

Screen Shot 2016-04-06 at 12.57.24Simplistic architecture of a webview based hybrid app. Access to native device functionality is provided by Javascript - native bridge while the main app UI and logic run inside a webview.

Another problem is usability. Android and iOS users are used to apps that look like - well - iOS and Android apps. When the UI is running in a webview, it often looks like a web app or some sort of combination of Android and iOS UI elements. The Hybrid app framework developers have tried to counteract this by creating different CSS styling for iOS and Android, but this is really far from optimal.

Device and mobile browser fragmentation is another hurdle to cross in creating a code-once-deploy-everywhere HTML5 hybrid app. iOS and Android have different browser engines and therefore support different Javascript functionalities in their browsers. To make matters worse, different Android phone manufacturers often have different versions of Android browser. Even the same manufacturer might have fragmentation in their browser engine solutions in different phone models. Crosswalk project is a pretty decent effort to handle this problem. The idea is that, you package the crosswalk browser engine inside your app, so you can be sure that each device running your app does it with the same engine.

Non web based solutions

Qt

One of the first non webview based mobile cross platform solution was Qt. Nokia developed it to provide a C++ based environment for making apps to Meego and Symbian platforms. Pretty soon it started offering the possibility to develop apps for Android and iOS. The problem with Qt was that it was really difficult to create native looking apps with it. Maybe because of this, it never really gained traction among mobile developers.

Xamarin

Xamarin is a cross platform tool that has been around for a while and doing quite well. Actually, they just got acquired by Microsoft and as a consequence, Xamarin is now offered free with Visual Studio. Xamarin's idea is that developers can use C# MONO-.net framework to build their apps. Xamarin's solution to make apps look familiar to each platform usage is kind of unique: they have wrapped almost the entire Apple CocoaTouch UI framework and Android's UI framework for C#. So developers familiar with these APIs and C# feel right at home. The problem with this is that, UI or view layer of the app needs to be written separately for each platform. As a positive side, this encourages making the View component as slim as possible, but it doesn't really deliver the code-once-deploy-everywhere promise. For example, an iOS AlertView would be created like this:

UIAlertView alert = new UIAlertView () { 
    Title = "alert title", Message = "this is a simple alert"
};
alert.AddButton("OK");
alert.Show ();

// ...and then the Android stuff would be done separately. 
// Most likely in a different file

Another problem is that wrapping all the API's does cause another layer of abstraction which in turn may cause new bugs. I've read it happens quite a bit. Xamarin does have the possibility to develop UI with Xamarin Forms. It is based in XAML, so Windows Phone and Windows devs should feel warm and fuzzy. This is what the same AlertView example looks like with Xamarin Forms:

DisplayAlert ("Alert", "You have been alerted", "OK");

That looks a lot better, but my impression is that Forms is still a bit limited in what you can do with it.

Getting rid of webview with the web based technologies

The biggest benefit of using web based technologies in mobile app development is the familiarity of the tech stack to web developers. That means a lot of potential talent is available. Fortunately, a couple of interesting frameworks have come around that remove the webview from the equation, therefore promising to deliver better performance. The basic idea with these frameworks is that also the UI code becomes native code instead of running in webview. This has become possible with the introduction of new web development platforms that actually abstract away manipulating the DOM directly. Instead, they rely on a declarative syntax, that describes how the UI is constructed and then - for web development use case - that is transformed into HTML that is displayed in the browser. For mobile apps, the browser can be replaced with e.g. native UI components.

Screen Shot 2016-04-06 at 13.31.28Simplified architecture of non webview based Javascript app development frameworks.

React Native

React Native is based on Facebook's React framework and it has attracted quite a bit of popularity. The iOS support for React Native is quite stable and Android support is evolving rapidly. Mostly the differences are in the amount of features supported. Certain UI elements are currently only available for iOS. There is a good overview on how React Native works. One big difference between React Native and React for web is that UI styling is not done with CSS as native UI components don't understand anything about it. Instead, React Native uses StyleSheet, which still looks familiar enough for people who know CSS. As to code-once-deploy-everywhere React Native gets quite close. You will likely need to write native plugins to your app for each platform and certain project based files such as the app.js usually needs to be implemented separately for both platforms. But most of the basic UI components will work with both iOS and Android. For more advanced stuff, a separate implementation is often required. For reference, this is how you would make the same ol' AlertView with React Native:

// Works on both iOS and Android
Alert.alert(
  'Alert Title',
  'My Alert Msg',
  [
    {text: 'OK', onPress: () => console.log('OK Pressed')},
  ]
)

NativeScript

Telerik's Nativescript has been around for a while. NativeScript doesn't abstract the underlying native UI components away from sight quite as React Native does. Instead, it uses it's NativeScript Runtime to allow calling native methods directly from Javascript. Here's a good explanation on how NativeScript works. If you don't feel like reading another blog right now, NativeScript is a bit similar to Xamarin in the code-once-deploy-everywhere department. A lot of code needs to be done separately for iOS and Android. To counter this, Telerik has developed a lot of Javascript modules that provide Javascript interfaces for the common UI elements. For example instead of having to write:

// iOS implementation
var alert = new UIAlertView();
alert.message = "Hello world!";
alert.addButtonWithTitle( "OK" );
alert.show();

// ...and so forth with Android

You can now write:

var dialogs = require("ui/dialogs");
dialogs.alert("Hello world").then(function() {
  console.log("Dialog closed!");
});

Telerik is also cooking something interesting with Angular 2. They wrote a good guest blog post to AngularJs blogspot about this back in December 2015.

Fuse

As React Native and NativeScript are done by big players, I wanted to mention also Fuse. They have some interesting ideas, such as providing a toolchain also for designers. Fuse has its own declarative syntax which from which true native UI code is produced from. The idea is better explained by a Fuse blog post here. I haven't had the time to test Fuse further, but it might be something worth keeping an eye on.

Time to look into the crystal ball

Regardless of all these interesting new tools, I'm still a bit of a native app dinosaur. I think that it's still the best way to make mobile apps. But getting rid of the webview is a step in the right direction towards making cross platform apps more tempting. If I were to make a cross platform app, I'd definitely do it with React Native, Nativescript with Angular2 or Xamarin and forget about the mess that webview brings with it. If I were a C# developer, Xamarin would be a no-brainer, but for the Javascript developers that still leaves two options. If Windows needs to be supported, that rules out React Native at the moment. But if iOS and Android is enough, my favourite of the bunch is React Native. Mostly, it's because I like how React does things in general and as those good things exist also with React Native I'd go with that. But if you're really into Angular2, it might be a good idea to turn your attention towards NativeScript.

Juha Riippi

Juha Riippi

6 kommenttia

Cool comparison Juha!
I think Qt is a major time saver for doing mobile app development, especially when doing animation-heavy UIs or custom user interfaces, ie UIs that shall look the same on iOS & Android.

We summarized our experiences with different frameworks & platforms here:
https://v-play.net/competitor-comparisons/qt-vs-html5-cross-platform-apps

Would be interesting to hear your thoughts about the current landscape, now that it’s 1.5 later than your original article was published!

Most cross platform solutions use Web technologies which basically means using Javascript. Bleh. For the life of me, I would never use Javascript other than for creating SPA.

This is why my company builds mobile apps with native languages (Swift and Kotlin) for the UI and share code by using C++ with a productive library like Qt.

In my opinion, best mobile apps are always better written in native code. Not Nativescript, React Native, nor Xamarin.

Peter Crocker sanoo:

We recently produced an full length report on Tabris.js, NativeScript, and React Native

vtntimo sanoo:

Hybrid, one codebase apps will be the future. We all know this deep in our hearts 😉

Nice recap. I suggest also looking into Tabris.js in this regaion:

Liity keskusteluun