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. [crayon-51dd7f6774fab/] 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, [...]
