Native or hybrid development: will the natives end up defeating the hybrid technology invaders? Or will the natives be the ones who end up in a reservation, has happened in the US?
This clash of civilizations, which mercilessly unfolds in our pockets and in our hearts, is far from its end.
To sort it all out, we have, in the right corner, weighing in at 75 kg and with multiple hybrid application under his belt, Arturo Batanero, front-end architect who is always about the o try to solve it we have, in the right corner, with 75kg of weight and multiple hybrid applications behind Arturo Batanero , front-end architect and always about to pull off the motorway when he sees the 'Cordoba' sign, wondering if is well written.
And in the left corner, weighing in at 77 kg and with a whole lot of native applications launched, we have Miguel Sesma, Android and iOS developer, software craftsman and always ready to try new things.
Now, you are the referee in the ring. Will this fight be decided on points? Or will it be a KO? Cast your vote!
[author_title id="abatanero" name="Arturo Batanero" title="Hybrid apps"]
Understanding native applications as those developed with each platform's SDK, a hybrid application introduces, by definition, a certain level of indirection between its source code and the executable with which the user interacts – which is something that doesn't happen or happens to a lesser degree in native apps.
You will agree with me that, from the performance point of view, the native application will always have an edge, which can be key to the perception of quality of the user experience, because ensuring quick response and move the UI at 60fps is an essential requirement.
Nevertheless, the trend we have been experiencing in recent years and which will continue in the foreseeable future is undeniable: multi-platform hybrid developments will take an increasingly greater market share away from the natives, which will eventually become a minority.
Why will this happen?
We all know that it happened before: in the desktop environment, because the progressive increase in hardware power enabled the rise of Java, we saw it was possible to effectively create applications that were no longer 'native', but rather compiled on an intermediate code and executed by a virtual machine, which may not have confined native C, C ++ and assembly programmers to a reservation, but significantly reduced their market share (a privileged niche, to be sure).
You know as well as me that we already have hybrid applications (in the sense of the article, using web technology) for desktop that effectively replace applications made in Java or C ++, including demanding types of applications, such as social network clients and development environments (how many know that the Slack or the Visual Studio Code clients are actually hybrid applications?).
My bet is that the same will likely end up happening in the mobile environment: the difference in performance between hybrid and native apps will continue to be reduced as the power of the hardware increases and JS virtual machines and local DOM implementations improve.
There will always be a difference in performance, but it will become increasingly irrelevant to the choice of technology, as those of us who have been in this for a while have seen.
Where we come from
First generation hybrid applications made use of a local or imported browser (web View), which was presented to the user on full screen and which, using HTML+CSS+JS, simulated each platform's native UI.
This is the focus of Phonegap/Cordova on mobile platforms, or of Electron and NW.js on desktop (which add a Node.js to the browser to build the executable that integrates both).
Obviously, this approach is limited by the quality of the implementation of the browser, which although fast on desktop (the previous example, Visual Studio Code, is made on Electron and is indistinguishable from a native application), still needs you to be strategical with what you choose the implement on mobile, always requiring an extra optimisation effort to come close to 60fps.
Where we are going
The new trend in hybrid applications is to skip the browser DOM and directly use native components, orchestrated from a JavaScript virtual machine that runs the JS program.
And it's no longer a full-screen web View. Now we have a UI consisting of native Android or iOS controls, configured and positioned using CSS and an SGML reminiscent of HTML, which are controlled from a JS virtual machine (V8 on Android and the native engine on iOS) that runs the program, interacts with the underlying OS, and abstracts the differences between the various platforms, among other things.
This is the focus of NativeScript and React Native, still in its infancy, as you, Miguel, correctly point out, but in rapid process of maturation. Using them, we can assemble applications (see on Android or iOS) that, for example, move a list of hundreds/thousands of photos at 60pfs as if they're native – because, in that sense, they are natives.
They offer the best of both worlds: combine the native user experience with the web development experience.
If the {NS} application is developed in Angular, all of its advantages can be incorporated: thanks to its radical separation of views and models, it allows you to run the same application in native and web mode (you've been a bad boy here, Miguel), simply adjusting the views, as well as run the framework and the app in one or multiple threads, leaving the main thread only to handle the UI and deal with the underlying OS.
And as for this latter aspect, things have also improved significantly: in NativeScript, for example, we are no longer limited, as we are in Cordova, to plugins that must be programmed for each platform in order to use native APIs.
Now you can call any OS function directly, thanks to a type conversion proxy that, although adding a level of indirection, grants you access to the full functionality of each platform. You no longer need a native programmer to make you a plugin to get it. The plugins would only be needed, for example, to integrate pre-existing code libraries – not to use the OS.
Additionally, the NativeScript team has developed an abstraction layer for the different platforms. It allows you, for example, to access a local file in the same way across all OS, but if you want to open it with the native API, you can do it.
Native code? Are you sure?
In Android, the 'native' code can barely be called so. In its earliest versions, the Java code was compiled 'Just in Time' in bytecodes on the Dalvik virtual machine, which is not that different from the JIT compilation of the JS code on a virtual machine like V8. Certainly not conceptually and, eliminating the DOM obstacle, increasingly less in terms of performance. And if you don't believe it, just look at the Node performances in the server, where there is no DOM.
Now with ART, instead of Dalvik, the code is compiled in development time, which, at the cost of a larger size, results in gains in terms of speed, but let's be honest – it's not exactly native.
iOS, on the other hand, does have a low-level compilation, which is why the use processors that are less powerful and have lower memory requirements is allowed, partially because they control the hardware on which everything runs.
So, Objective-C or Swift applications do seem truly 'native' to me, in comparison to an Android application in Java or in Kotlin (which, by the way, Miguel, I'm glad they follow the TypeScript model).
Clash of Clans
The evolution of hardware and web technologies (web GL will be the following leap for mobile, directly accessing the GPU the way we already do in desktop) will continue to reduce the performance advantage of native apps.
On the contrary, the advantages of hybrid apps will remain the same as now:
- Development cost: for multi-platform hybrid developments, the cost will always be lower and, depending on the circumstances, it can be much lower, as we increase the number of distribution platforms and/or the size of the project.
A hybrid application could potentially be distributed on iOS, Android, Windows Phone, MacOS, Windows, and Linux with essentially the same code base, the same development team, and with less need for coordination, because it's only one team.
- Development time: the 'time to market' for hybrid applications is inherently shorter than for native ones.
Set to solve the same functionality (because, easily avoiding your hook, Miguel, you can make the same type of applications if they are based on standard controls, which are the majority) with web technologies, the development time will almost always end up being shorter.
- Operational coherence and cohesion: there may and should be differences in adaptation between platforms regarding views, in MVC terms, but at the model level, there will only be one application, which will mean a similar progress rate across platforms and an integrated resolution of bugs, because there will be a single code base and a single team working on it, not several.
- Painless updates: a hybrid application can, if desired, be updated without having to go through the application store again. With a native app, there is no way around going through a new approval process that, especially with Apple (despite improving as time goes by), can never be compared in terms of time and cost to having full control over what reaches your users.
In short, if we are talking about a development:
- that is multi-platform;
- that can be built with standard native controls;
- where cost is a key factor;
- where development time is also essential...
...then, the technology of choice will be primarily hybrid in the near future, if it isn't already at present.
Native development will continue to be necessary where that extra level of performance and hardware proximity is needed, but if the applications must meet the requirements above, they will be mostly hybrid. I fear that the natives will again end up in a reservation... although they will always be able to open up a casino and live like kings.
[author_title id="msesma" name="Miguel Sesma" title="Native apps"]
Arturo, nowadays, more than half of the digital interaction between users and companies is generated through mobile devices. That is why corporate image and customer loyalty depend on the quality of the apps.
Native applications are developed in Objective C or Swift for iOS and in Java or Kotlin for android. Having Swift and Kotlin allows us to program using state-of-the-art paradigms, such as functional programming, or the assurance and robustness provided by strongly typed languages with null-safety. Arturo, Typescript was conceived so that Javascript could have static types. :)
Access to the platform
Native apps allow the use of the advanced features of each platform, take advantage of the graphics processors, and push each functionality to a level to which a hybrid app plugin cannot come close.
For example, the React Native camera plugin supports 12 properties and some eight methods, while the Android camera has tens of classes with hundreds of methods and properties.
Because native apps need no plugins, which take time to be developed, they can use the latest characteristics of the platform as soon as they're available.
Note that Apple updates the iOS of old devices and Android uses compatibility libraries to ensure that previous versions support the new functions.
Although there are plugins for hybrid platforms that cover most of the device's functionalities, the most evolved, technical, or modern functions will always be out of reach and, in any case, their flexibility of use will always be inferior to the native API.
Of course we can write our own plugins, but we will need native programmers for that. Access to the native code is also possible only through a plugin that slows down each call – the proxy that Arturo mentions.
Performance
Perceived quality begins with performance. Swift compiles machine code through LLVM and Kotlin does it through JVM and ART, in addition to being able to use C/C++ when necessary. Both platforms take advantage of the advanced functions of UI components: UITableView or RecyclerView can display lists with complex transitions, advanced animations, and smooth scrolling, consuming much less memory.
This is precisely the greatest problem of hybrid apps: for those running on a web view (Phonegap, Ionic, etc.), performance is much more dependent on its quality – a performance that is very variable and depends not only on the platform, but also on the device and on the version of the operating system; for those running on their own virtual machine Javascript (React Native, Nativescript), the huge weight of this machine on the consumption of memory and resources makes them ill-suited for low and medium-range devices.
We already know that Javascript is not especially effective in managing the UX. For example, one of the typical uses of an app is to display lists. A native list renders only what goes on the screen; a web list renders all the elements, which can be slow if they are many. To avoid this, you can use Lazy Load, but it will continue to be far from native performance.
Arturo, you yourself explain how the problems of hybrid applications are solved: by making them more native. React Native and Nativescript use native UX components to try to improve performance. And although it's true that they solve problems like the one I mentioned with the lists, they introduce new ones: we cannot make the web app with them.
We can generate apps for platforms that have their own graphical environments (iOS, Android, Windows Phone), but by not being based on HTML – instead, as you say, Arturo, based on an SGML that is reminiscent of HTML – they don't generate code for the browser.
There are some libraries that try to solve this, but their operation is limited and problematic. The use of UX components created with a specific language ties us down to a specific framework, which is the opposite of the multi-platform universality we were looking for!
In native apps, we can create as many threads as we want, there is support for coroutines and, of course, we can use services to perform work in the background: scheduling tasks at certain hours, completing the work in progress even if the user turns off the screen, running music in the background, etc.
In hybrid apps, system services are not supported and background tasks are limited to network access – and that's a best-case scenario! Nativescript runs all the code in the UI thread, although it allows the use of a worker thread in a very limited way.
React Native supports HeadLessJs, an equivalent to services with less functionality and it is only allowed in Android. It is far from equivalent, and you know it.
Getting these applications to behave as truly native requires a tremendous amount of work for native developers, optimising code and plugins, which reduces the cost-effectiveness of programming once for both platforms.
Other aspects to take into account
To summarise other advantages of native apps:
- Working in native mode allows development for all kinds of devices like Wearables (Apple Watch, Android Wear), TV or, Cars (Android Auto, Apple Car). Working in native mode allows development for all kinds of devices, like Wearables (Apple Watch, Android Wear), TV, or Cars (Android Auto, Apple Car).
- They provide greater security. The use of plugins and Javascrip in hybrid applications introduces new layers of complexity susceptible to be attacked.
- They improve battery life. The code is optimised for the architecture, makes better use of the different CPU / GPU cores, and requires fewer layers of software to run.
- They allow the use of native accessibility features, which are especially good in iOS. They open us up to all our customers and improves our corporate image.
As for the development environment, the IDE for native apps are truly advanced, especially in the case of Android Studio, based on IntelliJ Idea. XCode is also a powerful IDE, and both allow the design of the UI using drag-and-drop tools.
When it comes to debugging, they make the developer's task much easier. The code can be debugged from the IDE line by line or with conditional breakpoints. They have advanced profiling tools that show CPU, memory, and network usages in real time, and both platforms facilitate the implementation of unit and functional testing.
To develop hybrid apps, we have some IDE like web Storm (paid) or Visual Studio (depending on the version) and others with fewer features like Visual Studio Code, Atom, etc. which are fine, and utilities and plugins to generate UI or profiles. Nevertheless, none of these tools comes close to the specialisation and the 'integrated development environment' of the natives.
Analytics libraries, access to mBaaS (Firebase, AWS, Azure, etc.), marketing, and crash reporting have SDKs optimised for Android and iOS, which are tasked with automating data acquisition such as navigation between screens, executions or crash logs, and sending them to the cloud in the background, hiding the complexities from the programmer.
The update of a native app in the app stores is not as painful as you say, Arturo: on Android, it takes a few minutes, and Apple has improved a lot and promised to lower it from days to hours in the next few months.
Publishing in a professional environment includes the review by Apple or Google (which has greatly improved this) of the applications, ensuring their compatibility and security. Skipping this step by injecting new Javascript in the users' apps doesn't seem like a very good idea.
Synchronisation in the implementation of features between the different teams of native apps is usually one of the reasons invoked in favour of hybrid unification. It is important that the pace of implementation is set by the scrum and not each specific technology. In a hybrid app environment, we would also have to synchronise the apps with the web, the designers, etc.
Is it worth saving a small fraction in the software?
A project for a typical app includes many profiles: product owner, scrum master, UX designers, architects, backend developers, devops, etc. Using JavaScript applications to unify the browser, Android and iOS entails a small percentage of savings, even smaller if we use React Native or NativeScript, which will not work for the browser.
Cheaping out on the quality of the app at the cost of transmitting a worse corporate image to the customer and losing the loyalty of that customer is not profitable in the medium term. In the long term, we will likely end up having to spend more money.
There is a place for hybrid technologies. Some parts of the app may require very frequent changes, or disply content developed for the web. In these cases, adding some react code or a web View to our application can optimise the resources without compromising the overall quality.
In very small apps, it may make sense to have a hybrid version of an existing web, and if our investment in JavaScript code for the business rules is very large, we can consider a partially react native app.
Facebook does that, Arturo, and we already know how its battery usage goes. But if we are starting from scratch to make the app of the company and we want it to have a future, from my point of view, the way forward is native development.
[poll id=5]
Comments are moderated and will only be visible if they add to the discussion in a constructive way. If you disagree with a point, please, be polite.
Tell us what you think.