You (probably) don’t want a hybrid app

19 January 2018
| |
Reading time: 7 minutes

We are regularly approached by potential clients who want us to help them build or maintain mobile apps. Many are interested in hybrid apps : HTML5 web apps that run in an embedded browser, with most common code across iOS and Android. Typically, this use a framework such as Cordova (a.k.a PhoneGap) which wraps a web app up for distribution and provides access to some device-specific APIs.

The apparent cost savings of these apps are obvious, especially if your organization already has the skills to develop web sites. And as developers, we’re all about saving ourselves effort and not writing everything twice.

Our experience, however, is that hybrid apps carry hidden costs that are not immediately obvious. At Zuhlke Engineering Limited in the UK, we now advise our clients that, in virtually all cases, it’s better to build native versions of the app for each platform you want to target.

This doesn’t mean all hybrid apps are bad, or that it’s impossible to build a good one. For some use cases, hybrid apps are a good fit, but this is the exception rather than the rule.

First impressions count

For a mobile app, user experience is everything. The App  Store and Google Play store make it convenient to try things out. If someone tries your app and it takes more than a few seconds to start, or has an unpleasant or sluggish user interface, they might leave a bad review, or (worse still) just try something else.

iOS has extensive Human Interface Guidelines , and Google has similar guidelines for how an Android app should look and work. Users expect the apps on their phone to use the standard UI patterns, like the rest of the apps on their phone. For example, to go “up” in an information hierarchy on iOS, you swipe from the left edge; on Android, there’s the physical ‘back’ button, but no swipe gesture. If you’re building a web app from scratch using Cordova, you may have to implement behaviours such as this yourself, for both platforms.

You can save yourself some work with a framework such as Ionic, which bundles Cordova with Angular, some stylesheet, extra build tools, and some components that render appropriately and have the expected behavior on each platform. But these can be hard to customise when you need more precise control over behaviour or appearance. 

Alternatively, you could decide you don’t care that the app looks the same on every platform. But this might only be acceptable in a few circumstances. In most cases, if you’re deploying your app to the public, you can expect your users to notice that something’s off, or get confused by unfamiliar UI patterns.

When it comes to performance, Apple suggests that a good launch time target for an iOS app is 400ms on the slowest supported device. If your web app uses Angular (which is bundled with Ionic) your users will have to wait for that to load, and this can take a long time. In some cases it can lead to launch times of five seconds or longer on older  IPhones, and even worse performance on Android.

Animations and interactions are also slower when implemented as CSS inside a web browser than when implemented natively. Pages might flash when loading. Even scrolling behavior is different, and usually more sluggish. You might decide that this is an acceptable trade-off – but your users will notice.

The situation is worse when it comes to supporting phones’ built-in accessibility features. Native components are accessible by default, and VoiceOver and Talkback behave predictably around them. Web components, especially custom modals, menus, and alerts, do not. You may well have to re-implement the logic to trap focus inside modals, move the screenreader cursor to the correct element, etc. yourself. You may decide this is an edge case that you do not care about, but accessibility is usability, and if your app is being released to the public, it’s not unreasonable for disabled people to expect your app to support the features they rely on .

The shared-effort fallacy

A common motivation for hybrid apps is only having to write the business logic and user interface once, without needing expensive iOS and Android expertise.

This is mostly true until you need to do something that relies on a feature of the device, such as the camera, or fingerprint reader. Cordova’s plugin architecture allows JavaScript to invoke native code on iOS and Android, and there are ready-made plugins available for basic functionality, such as taking a single picture from the camera or verifying a single fingerprint. But for everything else, you’ll have to write the code yourself. In practice, it’s almost impossible to avoid writing at least some native code.

Sometimes a feature will exist on one platform, but not another. The result is often a codebase that is full of per-platform code: “if iOS, run this long, intractable code block; if Android, run this other, subtly different code block.” It looks like two separate code bases merged into one, because it is.

Still, if “write once, run everywhere” works 80% of the time, surely it saves 80% of development effort, and reduces costs by 80%? This only works if you ignore the costs of testing . Unit tests are worthwhile but, when  it comes to mobile apps, it’s even more important to test on real devices-especially on Android, where different phones have wildly diverse performance and feature sets.

It’s worth noting that the iOS and Android web browsers have subtle quirks and differences. While it sounds nice to be able to write one UI in HTML and CSS that renders anywhere, those of us who’ve been in this game long enough to have to worry about supporting Internet Explorer know this is a chimera. The quirks in the different platforms’ browser implementations can lead to platform-specific bugs which you may not know about … until your users report them.

An annual barber’s appointment for Mr. Yak

Mobile platforms move fast. iOS now receives a major update every single year in mid-September. Major Android releases happen every year too, although hardware fragmentation means that uptake for new Android  releases is significantly slower. With these releases come new features, which may be supported ‘for free’ by the platform; new releases also bring deprecations, and breaking changes to the APIs.

Your users will expect to be able to update their device and for your app to continue working immediately. This is why Apple and Google release betas around three months in advance, to allow developers to test and iron out any incompatibilities well in advance of the new OS’s general availability.

In mid-July 2015, a bug was raised against Ionic and Angular on iOS 9 beta 3. A regression in UIWebView‘s window.locationimplementation Caused Angular apps to end up in an infinite digest loop, effectively breaking navigation. A workaround for this bug was provided by the Angular team on 11th of September, two days after the iOS 9 Golden Master was released, when it became clear that theUIWebViewbug wouldn’t be fixed. In the Ionic team’s blog post on 12th September, they wrote :

there’s time to make the iOS 9 roll out if you test, fix, and submit ASAP […] Unfortunately, we assumed these glaring bugs would would be fixed in time but they were not.

Given that the App Store review time could be up to a week, some developers using Angular and Ionic in their hybrid apps weren’t able to push fixes in time. What’s interesting here is that the regression wasn’t caused  by Angular or Ionic, but in iOS itself. But from a user’s perspective, it made no difference. The apps were broken on iOS 9.

With Cordova, there are three places from which regressions or breaking API changes can propagate upwards and present as defects to the user: they could be in the iOS and Android APIs, or in Cordova itself. Ionic adds two extra layers (Angular and Ionic itself) on top of these. That’s five huge, complex dependencies for your app you need to keep abreast of. and this is without even beginning to count the rat’s nest of NPM dependencies that forms many Javascript apps.

At the time of writing, in mid-December 2017, a newly-generated Cordova app generates 11 deprecation warnings when opened in Xcode. Plugins can add dozens to this figure. And Cordova still does not support the iPhone X’s edge-to-edge display out of the box, over six weeks after it was released.

In a world where hardware and software moves so fast, is it sustainable to rely on a complex web of dependencies to ensure your app looks nice – or even work at all – on the newest platforms and devices? The dependencies that matter the most are the operating systems and their APIs.

Thirteen amps and three square pins

Most of us who’ve travelled internationally will have a menagerie of power adapters at home. My own electronics scrapyard has at least three UK-to-mainland Europe adapters (only one of which fits hexagonal Swiss sockets) along with a couple of American adapters.

A lot of the cheaper adapters on the market are awkward to squeeze UK plugs into, because of small violations of the BS 1363 standard. Some are loose, which is even worse because of the risk of exposed contacts. At best, this can lead to a tenuous power supply; at worst, it can lead to damaged equipment, fire, and electrocution.

This may be acceptable if you need to charge your phone in a hotel room for a few nights. But it’s a hack. If you were the facilities manager for a British company expanding to new offices in New York and Amsterdam, you wouldn’t populate their kitchens with kettles shipped over from Britain with plug adaptors thrown in. You would fit the kitchens out with appliances bought locally. 

This is the problem with hybrid apps. They are a hack. A hybrid app will usually work, just about. But they typically provide a sub-par user experience compared to native apps, and less flexibility than comes with just building a website. This might be a trade-off you’re willing to make to get your logo in the App Store and on to your customers’ home screen, but you must decide if you want them to associate your brand with a mediocre user experience.

And then there’s the problem behind the scenes: your complex web app is encased in a hybrid app framework, which is itself encased in a complex scaffolding of native code. The whole stack appears like one of the contraptions in the Wallace and Gromit films, supremely intricate and impossible to understand or maintain. At this point, your team needs more than generic web skills to progress. You might as well have written a native app.

The temptation of familiarity and reduced effort is obvious. But for anything remotely complex, development can spin out of control into yak-shaving or painstakingly trying to reproduce weird rendering bugs. I’ve been that person too many times to recommend hybrid apps as a good mobile strategy.

Comments (7)

Peter

19 January 2018 at 20:12

So true. Saw a lot of hybrid apps with motivation to save budget. All did not match expectations and were more expensive then true native apps. Same with Xamarin.

John

21 January 2018 at 10:59

Very true. That said, part of the motivation is also expertise and skills gap.

    Jonathan Rothwell

    Jonathan Rothwell

    22 January 2018 at 13:30

    Of course. This is a classic anti-pattern in our industry. People tend to try and do the easiest stuff first, when all the risk is in the difficult stuff.

    It’s almost impossible to avoid doing at least some native development with a mobile app. The more you kick that unknown stuff into the long grass, the harder, riskier, and more expensive it will be to learn the native skills you need to fix that one weird rendering bug or that crash with some exotic custom Android launcher.

Aaron

Aaron

20 February 2018 at 15:41

Very interesting article. We had and still have some of the described issues with an Ionic hybrid app in an ongoing customer project. Ionic’s own point of view concerning “Hybrid vs. Native” development can be found here: https://cdn2.hubspot.net/hubfs/3776657/Ionic_HybridNative_eBook_Jan_2018_v8.pdf

    Jonathan Rothwell

    Jonathan Rothwell

    5 March 2018 at 16:43

    It’s good to see the Ionic team’s ‘sales pitch’ but naturally I disagree with a fair bit of this – particularly characterising hybrid app development as ‘fast’ and the cost of maintenance as ‘low/moderate’ versus a pure native app, which doesn’t match up with my own experiences.

    I’m also rather surprised to see them trumpet the value of ‘using the talent you already have.’ The implication is that you can avoid spending any money on hiring native development experts, or up-skilling your existing developers on native development. Nurturing your staff and giving them an opportunity to grow is a good thing anyway, but failing to prepare for the unavoidable bits of native development you do have to do will lead to frustration and delays.

Michael

Michael

7 May 2018 at 12:48

100% agreed. And according to my experience, it’s not only true for hybrid apps based on web technology, but for other cross-platform approaches as well (e.g. Xamarin, like Peter said). In any app with some amount of complexity, you’ll have to address some platform-specific behaviour at some point, whether it’s in the UI or “under the hood”. And the user experience is almost always lacking in some aspects in the end.

Rashad

26 September 2018 at 12:32

I would have fully agreed with this article if I was reading it 5 years ago. Today’s mobile phones hardware is able to run hybred apps without any noticeable difference for the user.
There are thousands of successful hybred apps in the app store and google play store. There are even successful games developed using a cordova+javascript
Plugins exist for almost all ios+android functionalities.

×

Sign up for our Updates

Sign up now for our updates.

This field is required
This field is required
This field is required

I'm interested in:

Select at least one category
You were signed up successfully.