Creating apps with PhoneGap: Lessons learned

      Requirements

At first glance, PhoneGap provides a very easy tool to help web and mobile developers quickly get their app to application stores using one codebase. With this article, I’ll help you dig a little bit deeper into how to use PhoneGap to take advantage of a few tricks of the trade that can help you develop faster and produce better applications. In this article, I share lessons that I learned while developing with PhoneGap for both Android and iOS devices for the popular social-drinking application, Untappd.

Doesn’t PhoneGap just work?

Let’s face it—we all know why we use PhoneGap: It’s one of the best tools out there to help take mobile and web-designed applications and transfer them to native App Stores without having to learn new languages. PhoneGap  APIs are simple and easy to use compared to HTML5 functions. PhoneGap APIs make developing that much easier, however, with all great power, comes great responsibility.

 

When developing simple applications that don’t require a data connection and serve static information, the PhoneGap solution works without fail. It does what it’s supposed to do: It allows web developers to build native applications with HTML5, CSS, or JavaScript. When you add more complex CSS3 elements, heavy transitions, and supporting multiple devices (such as iOS and Android), however, it makes you realize that there are few steps you must iron out to prevent hair loss.

Through developing for PhoneGap, I’ve learned a lot of tips and tricks to make your PhoneGap apps perform well and even better than its native counterparts. Some web developers overlook a major concern when developing PhoneGap apps: We forget that our app will run on a device that has far less CPU and memory power than our desktop.

Lesson learned: Understanding native design and development patterns

When you first look at PhoneGap website, the most powerful phrase that jumps out at you is its ability to publish one codebase to up to seven different application stores. While that is certainly true, it’s important to understand the design and development principles for those devices that you plan on supporting as a native application.

 

First and foremost, your PhoneGap application must act and feel like based on what users have come to expect from native applications versus web applications. For example, don’t require the user to “wait” to perform an action, such as a Friend Request or to “Like” something. Ideally, let users go about their business in your application without showing them the dreaded “loading symbol.” Instagram does a great job with this, especially around posting photos.  Once the user selects the filter, Instagram starts uploading the photo to their servers. The user still has to enter the caption, location,  and sharing option, but the photo gets a head start. This makes the experience fast and easy for the user. If the user decides to change their selection, Instagram deletes the photo later. Keeping up with this development pattern can help your application feel more native and as if it is working faster.

On the design side, there are very important layout patterns to follow. For example, let’s take a look at a popular Android and iOS application called foursquare.

iOS
iOS

Android
Android

Figure 1. The foursquare app interaface on the iPhone and on the Android

While the two interfaces look very similar from a content perspective, they have one key difference in the form of a navigation and action bar. On iOS, the navigation bar is located at the bottom of the interface, while on Android, the navigation bar is located below the foursquare banner. This design pattern is common across many other applications including Twitter.

 

The main reason that the navigation bars are switched on these platform is the presence of the physical or soft buttons that exist at the bottom of the device on Android. Adding a navigation bar at the bottom might cause the users to “fat finger” (to mistakenly press) the physical or soft buttons and interrupt their experience.

While this may seem like a small change, beauty is really in the eye of the “holder” of the device. As a developer you want your app to mesh with the other apps on that platform; you don’t want your app to appear to be a clone of an app intended for another platform. Understanding the design principles of your target platform can help your application appeal to that user of that platform. You don’t want to an Android user to re-learn how to use your application because it doesn’t conform to common Android design patterns. While this may require creating multiple code bases, it’s really only the header and footer that need to change, not the inner content (that should always stay the same). These sorts of user interface tweaks can make your PhoneGap application feel much more native and provide the user with a better experience.

Lesson learned: Living by DOM

The DOM, otherwise known as Document Object Model, isn’t quite your best friend when building PhoneGap applications. One of the downsides to making rich, feature-heavy transitions and effects is the number of times that the DOM must change. For example, when you click a button and want an overlay to appear on the page, you must alter the DOM to show that element. On a desktop computer, this process is seamless because your browser has a lot more resources to work with and the Javacsript-rendering engine is better. Mobile browsers generally lack those resources.

 

What’s even more concerning is differences between running a web-application through the mobile browsers (Safari for iOS, Browser/Chrome for Android), and their native Web View components (which is called UIWebView for iOS and WebView for Android). With PhoneGap, those two objects are combined into a single entity called the Cordova WebView.  In iOS5, Apple introduced a JavaScript-rendering system called Nitro that compiled JavaScript using JIT (Just-In-Time) processing. This helped the browser quickly load the JavaScript only as was needed, speeding up page loads. The downside to this is that any third-party applications running in the UIWebView (such as PhoneGap) are not be able to use this feature, as it is disabled. With this in mind, your web app might run faster in the native Safari for iOS browser than in your PhoneGap Embedded WebView. This creates a unique problem for applications that use JavaScript heavily.

Also, as you start to add more complex CSS3 elements, or hide and show pages with complex HTML structures, you might run into a situations where your applications become sluggish. Page transitions may cause the screen to flicker and load content in a choppy way. These type of actions degrade the user experience and make your app feel only like a web app, instead of a native app.

While there are many solutions to conquer this problem, there are some solutions that I have found that help you miminze choppy loading and increase performance:

1.    Hardware acceleration for your browser

Given that your target web browser must support WebKit (specifically on iOS), you must specify the browser to add hardware acceleration to certain elements. You can do this by using the CSS properity translate3d. Typically you use this element to translate elements on a page, however, if you use the properties and don’t set any parameters, it specifies to the browser that it should start rendering content using browser hardware acceleration. Say for example, you have your HTML structured as follows:

<div id=”content-area”>        <div id=”page-1” class=”page”>      …    </div>     <div id=”page-2” class=”page”>      …    </div> </div>

You must apply the translate3d properity to the div.class element as follows:

div.page {        -webkit-transform: translate3d(0,0,0); }

The above code triggers the CSS to be hardware accelerated, which makes scrolling and transitions much smoother on your iOS device. On the Android side, I have seen weird side effects when using this technique; I do not recommend using this property on that platform. However, the rendering on the Android WebView (especially on larger devices) appears a little more powerfully than on iOS.

 

Note: This code only works in WebKit browsers. Remove the –webkit- prefix to allow this to work in other browsers.

2.    Gradients and Box Shadows are a developer’s worst friend

With the introduction on CSS3, using Gradients and Box Shadows allow most web developers to create awesome visual elements. However, these properties are very taxing on a mobile brower. In my experience, I have seen that removing gradients from item rows can increase performance significantly. Use these properties sparingly in a “News Feed style” and don’t apply them multiple times within in your structure. You can still use these styles for buttons and for other one-time elements, but stay away from using them in feeds or in areas where you are changing the DOM structure frequently.

3.    Use templates and pre-compile them!

When building Untappd version 2, we were getting data from our server in JSON format and wanted to build re-useable templates to quickly format the data and display it to the user. We settled on using HandlebarsJS because it offered us the ability to add logic into our templates and the ability to pre-compile the HTML templates into JavaScript-optimized versions for better performance. Through compiling, we were able to increase page rendering by two times compared to the time taken to page render pages that were not pre-compiling.

4.    Minimize your DOM structure

When building your HTML structure, most web developers don’t need to worry about reaching the limits of children nodes in an HTML structure. With a mobile device, however, you are limited because of the maximum memory allocation to the WebView. Believe it or not, you can crash a WebView due to an excessively large HTML structure. A great way to decrease your HTML footprint is to decrease the child elements your main structure.

For example, if your HTML structure looked like the following:

<ul>         <li>           <a onclick=”doSomething();”>Stuff</a>         </li> </ul>

You could always change the structure, as follows:

<ul>         <li onclick=”doSomething();i>            Stuff         </li> </ul>

This can save you an extra level and, of course, you could always swap out onclick for ontouchend to have your code perform better on your mobile device.

 

Of course this is not the be-all-end-all list of improvements you can make to your PhoneGap app, but these tips can ceratinly help you improve the performance and usability of the app.

Lesson learned: Testing and debugging

One of the most complicated tasks when building your PhoneGap app is debugging and testing. With a web application designed for mobile, you have the ability to quickly push fixes to your users, but, when submitting your application to the store, you are subject to the approval process for updates, which can take some time. Therefore, it’s imperative that you test your application extensively before launching it.

 

With this in mind, it can be very difficult to test an application running on a phone. On the web, there are tools like Web Insepector and Firebug that allow you to see XHR requests and inspect DOM elements, however, testing on the phone becomes a little more challenging. Luckily, PhoneGap offers a great tool that can make debugging those nagging issues a lot easier.

Weinre, a DOM and XHR inspector, is a tool availale for remote debugging of PhoneGap applications. With Weinre, you are able to see XHR requests, inspect the DOM, and do JavaScript profiling to see when and where re-flows occur in your application. To get started with Weinre, just add a simple line of JavaScript to your index.html file, as follows:

<script src="http://debug.phonegap.com/target/target-script-min.js#anonymous"></script>

It’s very important to make sure you change the default hash (in this case #anonymous) to something unique and secret so that no one can access that page. If you do not, an unauthorized user could potentially have access to your code via the Web Console.

Once you have done this, browse to the PhoneGap Debug page. Follow the steps listed and make sure to include the unique hash that you used previously in the text box. Once you complete this you can now use the Web Inspector and XHR tools to get a better idea of what is going on under the hood of your PhoneGap app. This can help you troubleshoot issues quickly and more efficiently.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s