2014-05-20

Co.Labs

Our HTML5 Web App Flopped, So We Went Native (And Haven't Looked Back)

When building a mobile version of its jobs site, TheLadders found that the HTML5 route wasn't all it was cracked up to be.



Our first attempt at mobile was born out of a hackathon. Our team here at TheLadders had built a small app for job recruiters, turning to PhoneGap to craft something truly cross-platform. Not only did it let us utilize our existing expertise in HTML5, CSS, and JavaScript, but we were able to turn it around quickly. Best of all, it would be on all the major mobile platforms. Win-win, right?

Wrong.

Once we started building out the public-facing version of the web app, that hopeful rationale soon gave way to the stark reality of mobile app development. One by one, the challenges piled up. Before we knew it, we'd be switching gears and building native apps instead.

Why HTML5 Didn't Cut It For Us

While we initially thought that PhoneGap's smaller learning curve would be an asset for us as non-iOS developers, we quickly discovered that PhoneGap has its own peculiarities and technical challenges. The resulting experience looked and felt substantially less polished than that of a native app. Before long, we'd abandoned it.

As it turns out, the QA process of testing the app on iOS and all the various flavors and screen sizes of Android proved to be quite a chore. We spent countless days and weeks trying to massage the PhoneGap code into something that presented itself adequately on all platforms. We had to make painful trade-offs, which hurt the experience. Ultimately it was only released for iOS and proved to not be a successful product. We pulled it from the App Store.

PhoneGap was not the only reason the app wasn’t a hit, but it might have been symptomatic of a misguided approach. The goal of “write once, run everywhere” is a noble one. On the back end, most of the code being written today and deployed in production around the world is running on virtual machines. Java, Python, and Ruby all compile to bytecode and run seamlessly in a virtual machine on a variety of platforms. Native code is getting rarer. No one is writing a website in C. Native languages are increasingly niche platforms for circumstances where raw performance is paramount. You won’t see Call of Duty written in Java or Final Cut Pro in Ruby anytime soon, but you can bet a vast majority of the Internet’s websites are running on a virtual machine neatly distanced from whatever hardware is underlying.

The success of this virtualized approach on the back end has not materialized on the front end. Early cross-platform GUI toolkits like Java Swing helped change “write once, run everywhere” to “write once, debug everywhere.” Aside from the challenge of debugging on all possible platforms, user interface norms and patterns vary wildly from platform to platform. Mac OS X does not look or feel anything like Windows 8. Compounding the problem, cross-platform UI toolkits don’t mirror any of them.

Embracing Native App Development

So when the time came to work on our job-seeker app a year later, we bit the bullet and went native. We thought the smoother, more consistent and polished experience we could achieve with a native solution would pay off with our customers. With a strong engineering team, mastering Cocoa on iOS proved to be far easier than we thought. Lots of documentation and a strong developer ecosystem actually resulted in us moving much faster with native code than PhoneGap, and the app looked and felt much more modern.

The major disadvantage to this approach was that Android had to be developed completely separately. However, a lot of the complexity is generally in the service layer and we made sure to have an extremely clean and well documented REST API supporting the app. We chose to figure out the experience on iOS first and then port Android using the same REST service layer.

We began working on Android in September of 2013 and had a final build around Thanksgiving. With an iOS app serving as a prototype in hand and plenty of documentation and examples of the REST API, it was a pretty quick build. We also had the freedom to change parts of the UI to match the accepted Android UI idioms and gestures.

Of course, there are subtle and stark differences between iPhones and Android devices that your app must account for. Android has a very different navigation mechanism than iOS. Android devices also have a physical back button, so there’s no need to put one on the screen. The additional buttons on Android phones also make having bottom menu or toolbars cumbersome, and accidental clicks are common.

Going native really allowed us to effectively manage these issues and tailor the look, feel, navigation, and gestures of the app to the specific platform. Aside from solutions like PhoneGap, options like Titanium exist, which compile JavaScript into native code and use native widgets. With these options, even though you have native widgets, you’ll still need to somehow resolve the platform differences like back button versus no back button.

It’s all been a learning process, but we’ve moved through the conception to delivery phases relatively quickly and have now released a total of three apps for job seekers and recruiters. For now we are sticking with separate native implementations: We develop on iOS then write a native Android port. So far it’s working for us, but we like to reserve the right to change our minds.




Add New Comment

8 Comments

  • david

    Understanding the need for a good and possibly provocative title to garner readership, I think it is unfortunate that coding Hybrid apps is portrayed in such a negative light. There are obviously situations that call for native apps, but the time, money, and resources saved with Hybrid apps can be an incredible help. The question to go Hybrid or Native should be based on what platform best fits your requirements. To argue either one doesn't work is to ignore the incredible number of successful Hybrid and Native apps already in use. At least the author presents an open mind toward platforms at the end of the article. Unfortunately, by the time I was halfway through the article I was thinking it was unfortunate his team seemed to bite off more than they could chew technically and didn't seem to know about the multiple solutions out there (many being named by other commenters) that would have solved the issues mentioned.

  • You can get great performance using HTML but it's more than "already knowing HTML/CSS/JS" - and basically impossible if you decide to go with PhoneGap.

  • We're spending much of our time at Endloop looking for the best solution of mobile and native for the projects we are working on. We're a native mobile shop and for years that has been our solution, but as we're working with more and more startups and often require solutions early on that let us prove models before going full native...a better hybrid solution has been on our radar. Some very interesting front end mobile web frameworks right now that have us very excited for what is possible...a mix of Famo.us and Angular for example is providing mobile web performance like we've not yet seen before. That being said, to take full advantage of the iOS and Android platforms, native is going to be the only great solution for a good while yet.

  • We use Adobe AIR for 3 Large apps for LEGO and the national public service tv channel in denmark - and we see no challenges in going out on 3000 separate devices - except those cheap android performance killers of course - the game app we got going for all devices even includes phones in the same codebase - the back button and the menu button is just a nice addition to out UI - the thing to to note is that its always easier to use custom design when going crossplatform - classic component design is just not the way to go if you want to rely on "code once" - and yes as simon says the performance is blazing - at the end of the day with one code base in AIR you get really close to "write once, run everywhere" - ofcourse bugs happen and they get fixed, but its not because of the framwork - when you go native bugs happen too... and then its "write once, debug once" vs "write every where debug everywhere" - our code is just a clean as java or native-c so bug fixing is bug fixing

  • Did you consider Adobe AIR which compiles to near native performance and targets both Android and iOS with a single code base?

    simon