Developing Better PhoneGap Apps

Mobile Development, Tutorials Comments (42)

A few days ago, Chad mentioned that creating a mobile experience for your users does not have to come at a steep cost if you take advantage of the mobile web. The devices that are on the market today have full-featured browsers—they fully support JavaScript and CSS. If you’ve started researching what it would take to get from mobile web to native app, you’ve likely come across PhoneGap—a framework allowing you to wrap a mobile web app and deploy it as if it were written natively.

We’ve done quite a bit of work in PhoneGap lately and the question inevitably comes up: are apps built in PhoneGap “slow”? A quick Google search returns a page full of reasons that would keep you from wanting to pursue using web technology in your next app. Before you write it off, however, we’ve come up with a few tips that have drastically improved our own PhoneGap apps.

Test on the Device From The Start

The simulators are great at determining whether snippets of code will work or not, but they do nothing to emulate the actual performance of the device. Take it from us: there is a huge difference. It would be worth your while to test on a handful of devices as older devices may see even further impacted performance. These older devices act as great lowest common denominators, don’t cost much used, and have an added benefit of helping to reduce ewaste.

Listen for ‘touchstart’ instead of ‘click’

This is probably the most simple, yet most noticeable change you can make. There is a ≈400ms delay between the user interaction and when the “click” event is fired. While listening for touchstart instead of click does nothing to boost the performance/efficiency of your code, it will make the app respond faster and perception is everything.

Equally important is a responsive UI. When the user taps something, the app should immediately respond in some way. In most cases, simply applying a class (e.g. “active” to highlight the tap) to the selected item is instantaneous, but we found a few cases where some devices would get hung up during a larger JavaScript project. A great way to ensure a responsive UI despite the occasional JavaScript hang up is by using the :active pseudo-class selector in CSS. This style is applied immediately to an element when a user has his or her finger on that element.

a:active, {
 background: #AAA;
element.addEventListener('touchstart',function(e) {
 e.currentTarget.className = "active";

See a Demo
(Check it out on your iOS, Android, or BlackBerry 6 device; BlackBerry OS 5 and older, Palm, Windows Mobile 7, and Nokia do not have the touchstart event as of writing this.)

A word of warning when listening for touchstart: You will need to strictly manage how the user can interact with the UI—this means disabling and enabling items when appropriate. Devices like the iPhone can detect more than one ‘touchstart’ event at the same time (try pressing the bottom two buttons in the demo at the same time, then try pressing the top two at the same time).

Update: In the comments, Ciaran made an excellent point that I totally forgot to address: how touchstart can cause problems when your application requires scrolling. When you touch the screen to scroll, it triggers a touchstart, producing undesired effects if you’re listening for touchstart for user interaction. We’ve worked around this by listening for a touchstart, touchmove, and a touchend. If the touchstart and touchend occurred without a touchmove, then it was a tap. It is reinventing the click event, but without the delay.

Update 2: Here’s a little demo of how we’re using touchstart, touchmove, and touchend to simulate a “tap” instead of relying on the click event. The item turns grey when its been touched, and red when it has been selected. Notice how Item 2 (the only item using the “click” listener) has a significant delay between being touched and selected. I commented the source code in the demo to give some insight behind the logic of the code. This was simply pulled out of one of our projects, so it’s not ready for primetime in your application—it’s meant to give you a push start on implementing it yourself.

See the Demo
(Only works on devices that implement touch events.)

CSS Animations

If you’ve tried to use JavaScript to animate anything in the DOM, you were likely sorely disappointed in the results using mobile devices. It’s not necessarily because the devices are slow to execute JavaScript (although that’s part of it), it’s the reflow and rendering of the DOM elements that causes a slow down.

CSS animations allow you to skip the reflow and render—they can immediately be painted in the window. The key in getting good CSS animations, however, are developing them to take advantage of the hardware acceleration when available (especially in iOS devices). Currently, only -webkit-transform and opacity offer hardware acceleration on iOS devices.

See the Demo
(Check it out on your iOS or Android device.)

The demo shows three blocks that all animate to the right, and then back. The first uses jQuery for animation, the second a CSS transition of the left property, and the third a CSS transition of the translate property. This is a simple example, but already you can notice the performance difference between using JavaScript and the hardware accelerated transform. It may seem like a small difference now, but the difference exponentially increases with every addition to the DOM and each added level of complexity to the animation.

A word of warning: flickering. Test your CSS transitions/animations early and often on the device. They tend to flicker in certain cases. We found the worst offender to be the iPad after using the keyboard or interacting with any input form element.

Optimize your JavaScript

Global Variables

Avoid global variables if at all possible. Besides being good practice, the garbage collector will not automatically clean up any global variables and you will eventually notice an impacted performance.

Memory Management

Help the garbage collector by marking variables for deletion. For example, if you have an initialization function that will only run once, at the end of the function, have it delete itself.

function init() {
  //application code here
  delete init;

Update: In the comments, Alex and Matt alerted me that I was misusing delete here. I had originally acquired this suggestion from the Apple JavaScript Developer Guide, but using delete is incorrect. delete is for releasing properties of objects and implicitly declared variables. While it seems like using delete actually works within Mobile Safari, it’s not the correct way to do it–and it’s not supposed to work according to the ECMA specification. The goal is to release variables (functions) from the global scope if they’re no longer needed. In this case, this init function likely is landing within the global scope. The best way is to not define this function in the global scope in the first place–JavaScript will automatically garbage collect variables that are no longer in scope. I believe it would also work to assign null to init when you’re done with the function.

JavaScript only has a function scope. Variables defined inside of blocks (e.g.: for loops or if statements) are not scoped to that block—they’re scoped to either the containing function or the global namespace. Try to reuse iterators or temporary variables.

Get into the practice of declaring all your variables with var. If you omit var while declaring variables within a function, the variable is assumed to be part of the global namespace and will not be marked for garbage collection upon return of the function.

Try a Different JavaScript Framework

If you’re using jQuery, it may be contributing significantly to the slowdown. jQuery includes a lot of compatibility for browsers like Internet Explorer 6. This is a lot of extra code being loaded into memory that you do not need. Get to know the devices you’re targeting—what kind of rendering engines are they using? iOS, Android, webOS, and BlackBerry 6 all use some version of WebKit, eliminating the need for (most) compatibility code within frameworks like jQuery. Two great alternatives are XUI or zepto.js. Both have a much smaller footprint (<10kb) and offer much of the same functionality as jQuery.

Concatenate and Minify

Combine all your JavaScript into one file and minify the file prior to distribution. This should improve the loading time of your app. No other resources can be loaded while JavaScript is being loaded and executed. By placing everything into one file, it keeps this pause to a minimum.


Running your code through JSLint is a great way to quickly have a “second eye” look over your code and provide some optimization feedback.

Update: Since writing this, I’ve come to appreciate JSHint a lot more.

Update the OS

We’re referring specifically to iOS devices here. There were significant performance boosts in some of our apps when we upgraded our iPads from 3.2 to 4.2. The upcoming iOS 4.3 upgrade this Friday (3/11/2011) boasts up to twice as fast JavaScript execution using the Nitro Engine.

If you’re looking to release to the App Store, you may not have control over the iOS of your users (unless you specify that the app only works on 4.2 or later). But if you’re in an enterprise setting, you definitely have more control of the version of iOS running on the devices.

Split up the Work

PhoneGap provides a wonderful framework for integrating native code through the use of plugins. PhoneGap uses this for interfacing between the different device features such as the accelerometer or camera. However, it is also great for splitting up the work of some of the more processor intensive calculations in your application.

Find the processes which are taking the longest to complete and consider whether it would be worth your while to develop a plugin for this process (e.g. processing/resizing an image). Keep in mind that the plugin will have to be developed for every targeted platform.

Disable Multi-Tasking

Update: This used to make a bigger difference–there’s really no more benefit with the improvements in iOS 4.3 and iOS 5, as well as PhoneGap 1.0. However, we recommend making sure you stop timers when the app moves to the background otherwise they’ll queue up and when your app comes back to the foreground, they’ll all fire at once.

Another tip directed at iOS…and maybe a bit of a controversial one. We’ve found that PhoneGap apps left open in the background for too long don’t always resume as expected. Whether this is due to the fact that it had some memory taken from it while in the background we’ve yet to really explore. However, we’ve found that by preventing the app from resuming where it left off, there was improvement in the performance and reliability of the app. Of course, the huge downside is that the app starts over from the beginning every time (unless you implement your own resume functionality through cookies, for example). Users really expect their apps to pick up right where they left off so implement this tip with care. At the time of writing this, PhoneGap does not really communicate with the web application that it’s switching to the background or that it received a low memory warning in the background. (However, it looks like the upcoming 0.9.5 release of PhoneGap is hoping to include some of these features.)

Update: Use a Client-Side Templating Engine

One of the issues that significantly slows down the performance of an HTML-based app is the complexity of the DOM. (If you want a very technical explanation as to why, check out this post…best to read it after your morning cup of coffee, though). We explored a solution to this problem by using a client-side templating engine and saw significant improvements in our applications. By removing unused elements from the DOM, the time it took update existing elements significantly decreased and we saw an increase in speed and responsiveness in the application.

This is more than just a performance “tweak” however and really covers the overall structure of your application. Thus, it deserved it’s own post: How Well Does PhoneGap Scale?


You’ll notice that most of our tips are related specifically to the efficiency and quality of code in the mobile web app. Non-mobile browsers are usually a lot more lenient of poorly written code because they (often) have the memory and processing power to waste. You don’t have that luxury on a mobile device.

We’ve really enjoyed the flexibility that PhoneGap has allowed us to have while developing a few of our mobile applications. Not to mention the rapid development process from start to finish using web standards. These tips are only some of what we’ve found helpful during our development cycles.

Have you found any other helpful tips? Have any questions about other ways we optimized our PhoneGap apps? We’d love to hear how this has helped you while writing your PhoneGap app!

Are you interested in implementing a PhoneGap app for your organization?

The following two tabs change content below.

» Mobile Development, Tutorials » Developing Better PhoneGap Apps
On March 9, 2011
, , , , ,

42 Responses to Developing Better PhoneGap Apps

  1. Ciaran says:

    The issue with using touchstart instead of onclick is that it can mess with the expected browsing experience, the main one being scrolling.

    If a user tries to scroll down the page but touches an element that fires a ontouch event, the page will automatically load the next page whereas an onclick event will cancel itself if it detects any movement, i.e. scrolling up/down/left/right.

  2. Daniel Pfeiffer says:

    You make an excellent point, Ciaran. One of the big issues with touchstart right now is that every vendor is implementing them ever so slightly differently. If your application requires scrolling, using touchstart is going to produce unwanted effects.

    One solution that we’ve used is to listen for touchstart, touchmove, and touchend. If touchstart and touchend occurred without a touchmove, then it is a tap (and this actually more closely models how the standard iOS and Android interfaces respond). If there is a touchmove, then it was a scroll or a swipe or a cancel. It is kind of reinventing the “click” but without the delay.

    I neglected to mention that in my “word of warning.” I’m going back and editing it now.


  3. […] Developing Better PhoneGap apps If you’ve started researching what it would take to get from mobile web to native app, you’ve likely come across PhoneGap—a framework allowing you to wrap a mobile web app and deploy it as if it were written natively. We’ve done quite a bit of work in PhoneGap lately and the question inevitably comes up: are apps built in PhoneGap “slow”? A quick Google search returns a page full of reasons that would keep you from wanting to pursue using web technology in your next app. Before you write it off, however, we’ve come up with a few tips that have drastically improved our own PhoneGap apps. (tags: performance tips ios javascript mobile phonegap) […]

  4. Ben says:

    Daniel, can you share the code you guys use to compare touchstart, touchend, and touchmove?

  5. […] DiscoverThe Best Free Apple iPad ResourcesNice links here for you iPaddies.(tags: ipad resources)Developing Better PhoneGap appsIf you’ve started researching what it would take to get from mobile web to native app, you’ve […]

  6. jouni says:

    a workaround for the 400ms delay/scrolling is to use touchstart instead of onclick, but also check if the user is scrolling

  7. […] within an App wrapper such as PhoneGap, you ought to take a look at Float Mobile Learning’s Developing Better PhoneGap Apps. Coincidentally, there’s also an interesting story today on how all HTML5 apps […]

  8. Xavier says:

    You say “Find the processes which are taking the longest to complete”. I have not found a good technique yet within Phonegap to achieve this. Do you have any recommendations for profiling techniques within Phonegap applications?

    • Daniel Pfeiffer says:

      Truthfully, it’s been a mixture of guessing and checking by bookending segments of code in new Date() and comparing the before and after values.

      On a related note, a login form in one of my iPad apps was giving me a lot of grief with flickering. It seemed whenever the keyboard was used, all CSS transitions/animations started flickering. I ended up completely working around the problem by placing the login form in a modal view using a PhoneGap plugin to pass data back and forth.

  9. jussi says:

    Is there a way to get responsive input for forms on initial selection, that brings up the keyboard? I tried using the above technique (as per links), but with both ios and android, it didn’t seem to make much difference. On android the input selection was slightly faster, but on both systems the keyboard came up with a noticeable delay.

  10. SoFierce says:

    Thank You! Thank You! Thank You! Thank You! This is a really “snappy” solution to touch events. I almost abandoned my project until I found your tip (:active pseudo-class selector in CSS). I was getting painfully slow touchStart feedback. Now I’m back in action.
    Thanks again!

  11. Eric Burnley says:

    I know I’m a little late to the game here, but for click event replacement, I’ve been using the HTML5 Mobile Boilerplate Fast Button Click. It’s basically the Google Fast Button click mentioned above, but accounts for scrolling and other things. I’ve put it in place on a mobile website, and it’s much more responsive. Super easy to implement, thought it might help someone.

    Here is a test I did for work with several different touch events paired with touch styled media queries for moblie. Each subsequent screen (after clicking the next button) uses a different event, from click to touchstart to touchend to the fast button click.

  12. Srini says:


    Great article!

    Do you know if apps built with phonegap can receive push notifications when they are in the background? The sample code from their wiki suggests that the app has to be running (foreground?) for it to receive push notifications.

    A second part this question is: if the app could receive remote notifications, can it send events to the elements on the page – e.g. refresh table entries?

    Thanks in advance!

    • Daniel Pfeiffer says:

      Hi Srini,

      There are two different types of notifications on iOS devices–push notifications (received from a remote server) and local notifications (scheduled by the app on the device). Both are attainable with PhoneGap:

      Local notifications:
      Push notifications:

      As far as sending events to elements on the page, you cannot truly execute JavaScript or update the DOM while the app is in the background; changes will be queued and ran immediately upon resuming the app. But it sounds like what you want to do is for the app to receive a notification while it is in the background and have an updated view for the user when they return to the app. The easiest thing to do would be to update the table every time the app returns to the foreground. This way every time the app is opened (whether its from a notification or not) it will have the most up-to-date data.

      Hope that helps!

  13. Ari Lacenski says:

    I’ve just started with Phonegap development, and I was advised to use jQuery Mobile, which of course relies on jQuery core. The reason given was that jQMobile does a good job of emulating native UI components. I haven’t made the switch to xui because I’m developing by myself and don’t have the resources to roll my own UI elements. Can you comment on the tradeoff and what one could do to make xui or zepto look more native? Many thanks.

    • Daniel Pfeiffer says:

      Hi Ari,

      jQuery Mobile and the jQuery library together (even when minified) come in at over 170kb–and that’s just for the core for your application. We recently released a PhoneGap-based application to a client (a decently complicated application) where all the JS for the entire app only came in at 70kb (built on Zepto.js). It’s not so much the size difference (because really, what’s 100kb anymore) but it’s what the size represents. A difference of 100kb of minified JS is a lot of code. The real problem is that of all this code being stored in your devices memory and taking away resources from the rest of your app–much of it will never be used (like all the jQuery code for IE6). There is a noticeable performance difference in apps of any substance or complexity. At this point in the game, I am not considering jQuery Mobile for use in any of my projects (although I still follow it).

      That being said, I understand your dilemma. jQuery Mobile has a very attractive feature–it helps you build the UI of your app so that it looks more like a native app. If that’s a big need of yours, then you definitely don’t want to write it off just yet. But there are alternatives: Have you looked at Jo ( or iUI ( Thomas Fuchs has a great resource for micro JS libraries as–be sure to check it out!


  14. Don says:

    How can u call an alert feature when an app is in the background

  15. laminina says:

    Hi Daniel,

    Any best practices for the UI specifically for setting font size, image size…I’m using em’s values and the same HTML/CSS files doesn’t behave the same in iOS size and Android screen sizes? Any reason or am I missing something?

    Why 1em doesn’t look the same in different screen sizes …not even close! :p
    Thanks in advance for the help. 🙂

    • Daniel Pfeiffer says:

      Hi laminina,

      It sounds like you may have a misunderstanding about the way em sizes work–they are NOT an absolute measurement but a relative one.

      For example, if I set my body text to 12px and then set my header text (h1, for example) to 2em, it will appear as twice the size as my body text. What sounds like is happening is that you are using em sizes for all the text in your application so it is basing the relative size off the device’s default stylesheet (which has different fonts and sizes between Android and iOS). Try using px measurements or, in your body tag, set the default font size to 14px to standardize the default size across the platforms.

      Hope that helps!

  16. Daniel Pfeiffer says:

    I wrote a follow up to this post a few months ago that I believe a lot of people missed:

    It discusses using a client-side templating engine to improve the performance of a PhoneGap application. We recently released a PhoneGap-based application to one of our clients that utilizes the approach outlined in this post and it saw noticeable performance improvements and benefits.

  17. Alex Grande says:

    Thanks for this overview.

    One thing that you may want to modify in our article is that you shouldn’t delete variables names.

    function init() {
    //application code here
    delete init;

    … will result in a JSHint error because the delete keyword should be used on objects, not variables.

    • Daniel Pfeiffer says:

      Thanks for the heads up, Alex. I actually pulled that recommendation from the Apple JavaScript Development guidelines…but you are absolutely right. Deleting variables is (technically) not supposed to work. That’s just for releasing objects.

      The goal is to release unneeded variables/functions from the global space (such as an initialization function).

  18. […] Developing Better PhoneGap Apps :… […]

  19. Anurag says:

    this is really nice matter given here specially for the beginners

  20. Matt says:

    Actually the delete keyword in javascript is not for deleting objects, it is for deleting properties of objects. The reason this may seem to work is because you may be removing the property from the global object (window). But not all objects are deletable and you cannot delete a property that an object inherits from a prototype. The best you can do is remove as many references to an object as possible. Keep in mind that any closures referencing the object will keep it alive.

    More info:

    • Daniel Pfeiffer says:

      Thanks for the clarification, Matt. I’m fixing the article now. That silly Apple JavaScript Developer Guidelines got me all confused about this…apparently Apple got rid of that document since I wrote this article. Probably for the best…

  21. Laura says:

    Thank you for this article!! This is exactly the info I need.

  22. […] Developing Better PhoneGap Apps: Float Mobile Learning […]

  23. Kishan says:

    I was about to start a phonegap project and came across this excellent article. Thank you for your time to research pro’s && con’s of each point on which a app relies.

  24. Gregor says:

    Great article. Very good job, helped me…thanks

  25. […] Developing Better PhoneGap Apps – MORE INFO […]

  26. Omer Sinai says:

    Regarding “Use a Client-Side Templating Engine”. I beg the differ. The first part of the paragraph is correct “One of the issues that significantly slows down the performance of an HTML-based app is the complexity of the DOM.” Yet client side templating is not intended to simplify DOM complexity or to ease DOM depth. In order to ease DOM complexity just…write simpler DOM structure. Client side templating is intended to be a “do-more-write-less” mechanism. Moreover research show that client side templating is slower than any other alternative for DOM creation:

    • Daniel Pfeiffer says:

      Hi Omer,

      Thanks for your comment! You’re absolutely right that a client-side templating library is not (in of itself) designed to reduce the complexity of the DOM. However, the heart behind the recommendation was taking a look at how a lot of people are place their entire app structure into the index.html loading DOM elements that may never be used (it can also be a nightmare to manage for larger apps). A client-side templating library can help break those pieces up and keep the DOM “clean” so that it only contains the elements that are relevant to where the user is in the app. The performance gain was in cleaning up our index.html file and enforcing better practices in separation of concerns.

      This is not a one-size-fits-all solution because creating these elements dynamically can be very expensive. It’s important to evaluate which templating engine is being used. Some are faster than others–we’re finding that “logic-less” templating engines are often quicker because they don’t allow the execution of JavaScript from the template. There are also “compiled” templates which are even quicker. It’s true that templating engines are not the fastest option for DOM creation, but we’re also not finding it to be the bottleneck in our PhoneGap apps and it continues to help development which is why we keep them around.



  27. Pruthvi says:

    Hello can you suggest how/better ways to avoid whitescreen
    in phonegap application Thank you.

    • Daniel Pfeiffer says:

      Hi Pruthvi,

      I’m guessing you’re seeing white screens when
      navigating between views in your app? It sounds like you might be
      navigating away from index.html (for example, after tapping a link
      in the app, you send the user to page1.html). The in-between state
      of unloading the previous page and loading the new page causes the
      white screen. The best way to avoid this is to not navigate away
      from index.html and instead use JavaScript to change the DOM when
      you want to change the view.

      Hope that helps!

  28. […] Developping Better PhoneGap Apps […]

  29. ReiGn says:

    Thanks for your advices, very helpful

    I try your personal solution for replace onclick event and it work great. However, it create ghostclick or ghostfocus when we load another page with anothers inputs
    What did you use to avoid unexpected ghost click/focus? I try event.stopImmediatePropagation() without success (and not supported by android 2). I try also Fast button from google but he prevent only ghostclick

    • Daniel Pfeiffer says:

      Hi ReiGn,
      What you’re likely seeing is the device responding to the click event (which occurs 300ms or so after touchend). The click event needs to be cancelled. Alternatively, take a look at FastClick to handle all your tap/click events:

      • ReiGn says:

        I attach event to nodes as attribute, so i’m a little confused that a click can occur on another different node from this one.
        exemple :
        var text_add = document.createElement(‘input’);
        textAdd.ontouchend = funtion(){};

        (After several test, i’m pretty sure attach event to node like this is the best way (for performance) to code in JS, in mobile, or when we get a lot of elements and events.)

        Maybe a problem with bubbling on something, i admit i don’t clearly understand how this work.

        So, Thanks. I tried also their FastButton and it work great, there is however some unexpected behavior with it.

Leave a Reply

Your email address will not be published. Required fields are marked *

« »