Role of Web Based Technologies In Maximizing Code Sharing In Your Applications
I was recently approached by a colleague of mine with the following question: "What are the available alternatives to reduce the current complexity of developing for multiple channels?". In a nutshell he was looking for ways to maximize the amount of client code shared among iOS, Android and Web channels while still being able to use native mobile features if/when needed. So here is the answer I shared with him which I thought would be beneficial for the wider community (not to mention that we love open sourcing everything here at Microsoft these days including our internal discussion threads).
The first question I typically start with is “What are they trying to build”? For example if they require squeezing out every bit of performance then native will always come on top.
The second question I ask is “What is their developers’ skillset”? Now in this case they are coming from native development so they may be open to either C#/XAML or JavaScript(or TypeScript)/CSS/html.
The fact that he threw in the word web presence mixed with requirement for a consolidated code base makes the web sound like a viable option (we still need to address the two aforementioned questions). There are a lot of options with the web today (this could be a good thing or bad thing depending on how you look at it). So lets discuss some options here:
Browser/WebView Based Solutions
SPA based frameworks like Angular 5 (it will probably be Angular 6 by the time you read this post), ReactJS, or even VueJS which seems to be gaining a lot of traction recently are excellent options since the same code base used for the web can be integrated within native platform shells like Cordova and Electron. Cordova includes a plugin system that allows you to tap into native iOS and Android capabilities (along with a mini web server that hosts the files inside the shell) and electron which allows you to tap into native desktop capabilities on Windows/Mac/Linux. The catch here is that you are still using the WebView (fancy word for browser plugin within your native application).
PWA is not a framework but rather an enhancement to the web standards. Think about it as an extension to the HTML5 JavaScript Api. Its basically the addition to web Api called Service Workers which introduces offline support, push notifications, as well as creating a native shell for the web app. Now this is a tricky business today as different browsers are at different stages in their PWA journey. For example PWA under chrome is ready for prime time as shown in my recent blog post here. On the other hand Microsoft edge won’t bring support until Spring Creators Update and Safari is yet to add support and currently its only available under its Safari technical preview for Mac (I believe they recently activated it for their iOS). So millage may vary depending on the platform you are targeting, but support is improving every day so we should expect to have a solid PWA story by the end of the year.
WebAssmebly is again not a framework but rather an enhancement to the web. It will coexist with JavaScript and WILL NOT replace it. The idea here is that the web platform is getting a new low-level binary compilation format (think of it as the equivalent of assembly for the web. Hence the name WebAssembly) that will do a better job at being a compiler target than JavaScript. As an added bonus you get to pick the source language to program with and convert that to the binary format. So think programming in high level languages like C++ or C# which will get converted to WebAssembly which you can load along with your JS code. You can even interface with you JS code and vice versa. Most major browsers support it today.
So in summary this option focuses on selecting a SPA framework while augmenting it with great new capabilities of the web like WebAssembly and PWA with the added bonus of integrating all of it within a native shell like Cordova/Ionic and Electron. The main point to remember here is that these solutions allow you to write once and deploy everywhere (web, mobile, and desktop) but will inherit the inherent limitations of the web and will be limited to running inside a browser.
Native Web Based Solutions (aka Compiled Applications)
Compiled Web based applications are applications where the UI and the styling are compiled to native code. You typically don’t use CSS and HTML for the UI but instead a markup language that translates to native device code (to Java and Swift/Objective C). So you will be provided with a suite of components that you can use which will be translated to native UI components. Here you will get access to a limited set of CSS like features to keep the syntax you already know but behind the scenes they provide you with an abstraction since CSS is not being used but is simply being provided to make it easier for a web developer to start building UI components. You also use JavaScript for the business logic which will be run by a separate thread spun up in the compiled application.
The first option is NativeScript which can be described as a runtime for building and running "native" iOS and Android apps from a single JavaScript Codebase (you can use Angular or VueJS). This is not Cordova/Ionic and there is no WebView. We are talking about real native components and not Html/CSS/JS based components. So you will not write code that will manipulate DOM elements but instead you will use XML. This option requires you to learn both XML and JavaScript at the same time which may not be for everbody. It runs natively on the OS so you have access to all the native APIs. You can call anything on the device from JavaScript. You can think about it as NodeJS for mobile. It’s basically a V8 JS engine for Android or WebKit’s JavaScriptCore for iOS that sits on the mobile device and runs there and lets you create native apps. This is not Xamarin which cross compiles. There is no cross compilation in NativeScript. The code you write ends up running on the device and you have 100% direct access to Native APIs. Another advantage of NativeScript is that it can be embedded into any existing iOS or Android app which could be beneficial if you have already invested in existing code that you don’t want to rewrite but instead you would like to start developing new features in NativeScript and gradually migrate.
The second option is React Native which is very similar to NativeScript, but instead of using XML for building UI components you use a format called JSX which is a mix of JavaScript and XML. This is an appealing option for those who already have experience with ReactJS since the components will be the same with one main difference which is the renderer (part responsible for rendering the UI), since again you won’t be working with HTML/CSS. So you won’t be using something like <div> or <p> but instead you would use things like <view> or <text> which are mapped to real components within native development. Another advantage of React Native is that it supports ejecting which generates an Xcode project and an Android Studio project which could be beneficial if you decide that native web based solutions is not for you and would like to switch back to developing natively again. Finally, React Native recently introduced a project called React Native for Web which basically allows you to create a renderer that is platform agnostic and thus allows you to use the same code base to run your application on the web which is a big deal when it comes to writing once deploying everywhere.
So in summary this option focuses on utilizing your web skills to build native applications with special markup languages to work with native UI. The advantage here is you get access to all the native device components which means native performance as well. But it comes at a price since you cannot reuse the same code base to deliver the same application through the browser or desktop. React Native for Web has the promise of allowing you to reuse the same code base to have a web presence as well but its still in early stages at the time of writing this post. At this point you could argue that native web based solutions are not that different from Xamarin Forms. This is a valid argument especially if you factor in the fact that you are having to learn XML (it’s a different XML than XAML), but the main difference is that you will be using JavaScript instead of C# which means that its more accessible to someone who is more accustomed to using web technologies and you can in theory reuse some of that code to build a web/desktop presence.
Summary
At the end of the day there are a lot of options available today. There is no good or bad option in my opinion, but rather a viable or non-viable option given the team’s requirements and skillsets. I included a table blow that measures the three different solutions discussed in this post that create a native shell to make it easier for you to decide on the best option for your team.
* Depending on the nature of the application you are building it might not matter to you. But you may feel the sluggishness in some apps