HTML5 vs. Native
when using a Backend as a Service
Bryan Klimt,
Parse
Hi, I'm Bryan from Parse, and I'm here to talk to you about HTML5 vs Native in mobile app development, especially as it relates to using a Backend as a Service.
So, just to be clear from the get-go, what do I mean by "HTML5" and "Native"? Well, by "HTML5", I'm usually going to be referring to applications that were written primarily with HTML and JavaScript. Typically, these are packaged up as an "app" by using some framework that embeds the HTML and JavaScript files into the app package and displays them using some kind of WebView. By Native, I mean an app that was written specifically for a particular platform, using the languages and libraries most suited to that platform. But it's important to remember that this isn't an either-or, binary proposition. It's a spectrum, and apps can be somewhere in between.
Now, this is a much talked-about issue. So, what new perspective can I bring to the table?
Parse
•
Backend-as-a-service (data, users, push, ...)
•
Native SDKs
•
for iOS, Android, and Windows 8
•
JavaScript SDK
•
for apps, web pages, and servers
As I mentioned earlier, I work at Parse. We are a backend-as-a-service that provides data-storage, user management, push, analytics, and other features, primarily for mobile apps. And specifically, I'm the tech lead for our client SDK development, which includes native SDKs for iOS, Android, and Windows. But I'm also the primary engineer responsible for our JavaScript SDK. And we have many users who are using our JavaScript SDK to power HTML5-based mobile apps. So I don't have any
particular bias on this issue.
Our customers are developers, and we talk with them constantly to see which features they find most useful, and what their pain points are in developing their apps. So we get a lot of feedback from mobile app developers about why they have chosen to develop their apps in one way or another.
Standard Arguments
•
HTML5 WebView Apps•
easy•
cheap•
ubiquitous•
Native Apps•
“native” feel•
hardware integration•
software integrationAnd to be honest, the standard arguments you've probably already heard are pretty much right on. So I wanna get these out of the way right off the bat. HTML5 apps are easier to develop for multiple platforms, because you only have to build the app once, and then you can just package it up for each app store. Being easier pretty much automatically makes it cheaper. And since basically every phone on the market provides some kind of browser, you get much wider reach than you would trying to target platforms one at a time. As we algorithm geeks say, it's O(1) instead of O(n). But native apps have a lot of advantages. For one thing, they just _feel_right_. Buttons are in the right place. They work the way you expect them to. Menu items are where you expect them to be. And beyond that, native apps integrate better, with both the software and the hardware. You're going to have a hard time accessing the new 3D camera in your phone from JavaScript running in a web view. And as far as I know, there's no way to fire off an Android photo sharing intent from an HTML link. But this isn't really anything you couldn't learn just by searching the web. In fact, there's a great Google I/O talk from 2011 on YouTube that goes into a lot of detail on those topics. So instead of rehashing all these old talking points, I'd like to take a step back and try to put a little wider perspective on things.
1995
Linux
Filesystem
Networking
Graphics
Audio
UI
Filesystem
Networking
Graphics
Audio
UI
Filesystem
Networking
Graphics
Audio
UI
In fact, I'd like to take you back to the dark ages, all the way back to around 1995. Those of us who were programming back then remember there were several major platforms, which were almost entirely incompatible. Obviously, they had completely different UI frameworks. But they also had fundamentally different filesystems. In Classic Mac OS, you would store your application's images and UIs in a Resource Fork instead of in a regular data file. And those images were usually in the PICT format, instead of the bitmap format primarily used on Windows 95, or PNG or JPG or one of the formats best supported on Linux. Likewise, audio files on the various platforms used different formats, with different capabilities and tradeoffs. So your multimedia stack would need to be completely rewritten for each platform. Networking was barely existent at the time. By 1995, TCP/IP was starting to become a standard. But before that, if you were making a game for Windows machines, you'd probably use IPX for LAN gaming, whereas you'd need to use the proprietary AppleTalk on a Macintosh. What this all boils down to is that in the early days of desktop computing, you basically had to completely rewrite the entire stack for your application for every platform you wanted to target. I'm going to call this Level 1 cross-platform
development.
1996
Linux
Filesystem
Networking
Graphics
Audio
UI
Sun Microsystems released Java, and it really took off for a while. With Java, you could write your filesystem code, and your multimedia functions, and your networking routines just once, and they would run across all these different systems. Now sure, Java AWT or Swing apps _looked_ funny. And they couldn't use all the latest video card drivers, and copy-paste didn't always work the way you expected. But the point was that suddenly there was a way to save time and energy by writing code just once and getting very broad reach with users. While Java apps never really caught on with consumers, they were pretty successful with niche and enterprise developers, because the value proposition was so clear. I'm going to call this Level 2 cross-platform development.
So where did things go from here?
2001~Today
Linux
POSIX*, C, Berkeley Sockets
libjpeg
libcurl
webkit
git
OpenGL
Well, by the 21st century, the landscape had changed quite a bit. XP finally moved Windows onto the NT subsystem. And OS X replaced the Classic Macintosh OS with new BSD unix-based underpinnings. This meant that all of the major Desktop platforms were more-or-less POSIX compliant. They all had good C APIs. And by this time, TCP/IP was well-entrenched as a networking standard, usable on all of these systems with basically the same Berkeley Sockets API. This unprecedented level of standardization allowed developers to build libraries that would work mostly unchanged on every major platform. For example, libjpeg for parsing JPEG images. And libcurl for HTTP. Add to that OpenGL becoming standard across the platforms. And on top of these cross-platform libraries, even more complex cross-platform libraries were developed, such as WebKit. And even entire command-line applications like git could be made. So Level 3 cross-platform development is all about one thing: standardization. With standards-based APIs across the board, the economics of cross-platform development totally changed. Now, instead of re-building your entire stack for every platform, the majority of your code could be in system-independent libraries, with only a relatively thin veneer of platform-specific UI and system integration hooks on the outside.
GitHub for Windows
A great example of this kind of approach is GitHub for Windows. Git has a fully functional command-line tool that I'm sure is almost entirely cross platform C++ code. But GitHub built this native Windows facade on top of it, that makes it feel like it's really fits in with the platform.
It's a great example of Level 3 cross platform development, where standards allow hybrid apps that share most code, but have a native veneer. But an even better example of this kind of development is…
2005-Today
Linux
Chrome
Firefox
Web Browsers, like Firefox and Chrome. And by 2005, we had apps like Google Maps, and Flickr, and GMail, and Facebook. These apps proved that the web was now capable enough to be its own platform. These are consumer products that need to be pretty and integrate well. And the companies that made them had the resources to make native versions for Windows and OS X if they wanted to, but they chose not to. That says a lot about the quality of the modern web as an application platform.
Desktop
•
Level 1 - Rebuild all the things!
•
Level 2 - Write once, run everywhere.
•
Level 3 - Cross-platform standards.
•
Level 4 - The Web.
So to recap, you could break the evolution of cross-platform development on the Desktop into four levels, ranging from having to rewrite everything in the beginning all the way through standards developing into a new platform, the web, where you can write once and have an actual good user experience everywhere.
Mobile
The next question is "how do we apply this model to mobile cross-platform development?"
Rewrite All the Things!
Data Store
Networking
Business Logic
Users / ACLs
Push
UI
Data Store
Networking
Business Logic
Users / ACLs
Push
UI
Data Store
Networking
Business Logic
Users / ACLs
Push
UI
When the iPhone and Android first started to take off, it seems like we got reset all the way back to Level 1. The major phone platforms today all have completely different application development models. Android apps are written in Java, iOS in Objective-C, and Windows Phone mostly in C#. Android apps are written as Activities that
communicate with Intents and store data in SQL Lite. But iOS apps often use Core Data for data storage instead.
And notice that developers are more demanding than they were on the Desktop. They want to make their apps social, with a data store that knows who they are, and lets them share objects with other users. On Android that means logging in with a Google Account, or should you use iCloud or Microsoft accounts? To get a truly integrated experience, you have to rewrite everything every time.
So, have we at least made it to Level 2 yet, where you have an option to write once and run everywhere?
WebView Apps
Parse
Well, yes, we have, with the various toolkits that let you package an HTML5 and JavaScript-based app using WebViews. I put PhoneGap in the slide, but that could be one of any number of toolkits of the kind, like Titanium Appcelerator, or Trigger.io. The WebView toolkits take care of part of the story, handling mostly the UI and business logic, but this is where Parse comes in.
WebView Apps
Business Logic
Networking
UI
Users / ACLs
Push
Data Store
Parse
Backend-as-a-Service providers give you a shared platform for user-management, and a data store that's integrated. You can use access control lists to allow sharing data between users seemlessly, using the same model on every platform. With WebView apps and a Backend-as-a-Service, you can get a write once, run anywhere solution today.
WebViews are today’s Java.
That means WebViews are today's Java. But that's okay. I know some people hear Java and think of the baggage that comes along with it today, but it's not a bad thing. It provides an easy, cheap way to build an app with broad reach across pretty much every mobile device. Let me give you a quote to back that up.
“By allowing us to write once and ship
across multiple platforms, HTML5 has
historically allowed us to keep the
Facebook mobile experience current and
widely available.” -Jonathan Dann
Jonathan Dann of Facebook said, “By allowing us to write once and ship across multiple platforms, HTML5 has historically allowed us to keep the Facebook mobile experience current and widely available.” That's the good news. The bad news is this quote is from the blog post where Facebook announced they were re-writing their app as fully native instead of relying on the WebView approach. But I’ll talk more about that later. Let’s move on to Level 3.
Mobile
•
Level 1 - Rebuild all the things!
•
Level 2 - Write once, run everywhere.
•
Level 3 - Cross-platform standards.
As you may recall, Level 3 is about developing cross platform standards so you can share most of your code across all the different platforms, with just a native UI veneer around it. On the Desktop, that was things like C/C++, POSIX, and Berkeley sockets. So what’s the equivalent technology for mobile?
What about C++?
•
Android NDK
•
iOS Objective-C++
•
Windows 8 C++/CX
Could it be C++ and POSIX again? After all, all the major platforms do let you write code in C++ that interoperates with a UNIX-like OS. In Android, that means using the NDK. In iOS, you can use Objective-C++. And for Windows Phone, you could use C+ +/CX, their managed extensions to C++. Now, this is a possibility, but I wouldn’t bet on it. For one thing, the development experience of each of these stacks is relatively painful. Using the NDK in Android isn’t nearly as pleasant as the Java SDK. Likewise, C++/CX is practically a new language that most people would need to learn. And this still doesn’t address a large part of the stack developers need today. C++ doesn’t solve the data storage need, or the need for user management with social interaction. And it doesn’t help with each platform having its own APIs for sharing and push. So, what other options do we have for cross platform standards today?
Well, why not JavaScript?
Native UIs
Parse
With tools like Titanium Appcelerator and others, you can write your business logic in JavaScript, and write actual JavaScript code that can hook into native UI elements. So most of your code is completely cross-platform JavaScript with just a small native veneer. That takes care of the UI and the business logic. For the data model and the user management, that’s where backends-as-a-service like Parse come in. Using the Parse JavaScript SDK, for example, you can write your data storage and user management code in JavaScript and reuse the same code on every platform. Soon, you may not even need something like Titanium.
HTML5
as
Native
•
Chrome OS
•
Windows 8
•
Windows Phone 8
•
Firefox OS
•
Ubuntu Phones
A growing number of mobile operating systems are treating HTML5 _as_ native. It’s hard to tell the difference between a Windows 8 app written in HTML and JavaScript and one written in C# and XAML. Likewise, Chrome OS and Firefox OS are designed such that all apps will be written in JavaScript. These may not be the dominant OSes on the market today, but neither was Linux back in the day, and yet we’re still using many of the standards it set. If we want HTML5 and JavaScript to be the standard for mobile development in the future, we need to support these efforts. Organizations like Mozilla are pushing hard to develop cross-platform standards for hardware integration like battery status, camera access, and telephony control. With these standards, you’ll be able to write even more JavaScript that runs cross-platform.
JavaScript in the Cloud
And you can take this a step farther by pushing more of your business logic and analytics onto servers, and then you’re reusing not only the code, but actual running services. Then you can tap into shared services, like Mailgun to send email or Twilio to send texts. Those services can be the common shared libraries of mobile
Mobile
•
Level 1 - Rebuild all the things!
•
Level 2 - Write once, run everywhere.
•
Level 3 - Cross-platform standards.
•
Level 4 - Will the Mobile Web take over?
I think that’s a pretty good story for Level 3 cross platform development. We don’t yet have the complex kinds of apps built this way as we do on the desktop, but it is doable, and we should look forward to seeing more of them.
Or maybe we can skip straight to Level 4...
The Mobile Web
The mobile web. What’s stopping us from building web-only apps for mobile devices the way we do for the desktop? I think the best lesson we can take is from Facebook’s story. As I mentioned earlier, they recently decided to rewrite their mobile apps to be native, rather than relying on HTML5 and JavaScript. We should look deeper into why they did that, to see what’s stopping us from relying on the Mobile Web today. This can serve both as a list of reasons to use native, and as a todo list of things to fix if we want the mobile web to succeed. And since this is an HTML5 Developer conference, I think most of us do. ;-)
First of all, note that Facebook isn’t making native apps for the desktop. That means it’s not a religious argument. And it means that Facebook doesn’t believe HTML5 and JavaScript are incapable of giving a first class user experience. It must be something specific to mobile.
Improving JavaScript
•
More standards
•
More offline/caching options
•
Get processing off the UI thread
•
Background services
•
WebGL
And reading into Facebook’s announcement, a couple of things jump out. First of all, there just isn’t a good solution to offline support today. Sure, packaging your site as an app means you can access the static files offline, but what about the data -- the data from this user and others. You have to rely on something like localStorage, which is problematic in a number of ways. LocalStorage is often limited to a small amount, such as 5 MB. And that’s without any sophisticated mechanisms for pruning old data. If you want a smart caching policy that keeps around only the data that’s most likely to be useful, you’ll have to write it yourself.
And even if you do that, there’s another problem. JavaScript is typically single-threaded, and localStorage uses blocking apis, which may be slow, depending on the
implementation. Loading a lot of data from localStorage may have a visible impact on the responsiveness of your UI, and that’s just want Facebook found. The main reason why they switched was, in fact, UI responsiveness.
So we need to fix that, and we need to iron out a couple of other issues, like what does it mean to have background services. Push is a major feature for mobile apps that doesn’t have a clear analog on the web. Sure, you can use WebSockets to get updates without polling. But what happens when your app isn’t currently open? We’re going to need some kind of Mobile Web push standard if we want to stop relying on apps.
So, all that, and there’s just one more thing I have to mention.
App
http://xkcd.com/1174/
I believe there’s a law that says every tech talk should have an XKCD comic
somewhere in it. Or at least there should be. This one is an image of a mobile website, with a popup that reads “Want to visit an incomplete version of our website where you can’t zoom? Download our app!”
Don’t be this site. If you want to make an app by packaging up your website and putting in app stores for increased visibility, that’s fine. Go for it. But if you want the mobile web to succeed the way the web has on the desktop, stop pushing people away from it. You should only send people to your native app if you can truly provide a more compelling user experience in the app. And if you do, you should do it in a subtle way, instead of bashing the user over the head with it.
For example, here are some screenshots from the Twitter and Tumblr mobile websites. They have buttons at the top to let you jump into your app, which is often helpful since the native apps stay authenticated and have extra features. But if you don’t want to, then hey, the website is still perfectly functional. If you’d like to do this in iOS, you can Google for “Smart App Banners” or “CFBundleURLTypes” to learn how to make these buttons.
Thanks
[email protected]
@bklimt
Parse
Well, that’s all I have time to talk about today. If you’d like to chat about this, I’ll be at the Parse booth for a little while. And I’d also encourage you to check out Matt’s talk tomorrow at 1:30 in Sea Cliff for details on how to build a web app with JavaScript that uses Parse.