Cordova/Phonegap
From MakeICT Wiki
Contents
Cordova/Phonegap
Cordova/Phonegap looks and in many ways is a quick and easy way to build cross-platform mobile applications. It has earned a mixed reputation for performance, though, largely perhaps because there's a few "gotchas" and some misleading documentation that cause significant performance hits.
What you need
- iOS7 apps: Xcode 5.x (meaning you need to run OSX 10.8.5 or later)
- Android apps: The Android SDK, emulator and friends
- node.js, for installing Cordova and plugins, and keeping them updated.
- Cordova
- Crosswalk (see below)
- list of plugins below
- fastclick (or use touch events only)
- Your favorite editor
- Apple Developer License ($99/year)
Rules of Thumb, Phonegap/Cordova Specific
- Use Cordova, not Phonegap: Cordova and Phonegap used to be almost the same product but they have split and Phonegap offers no significant advantages and on the other hand adds another abstraction level which is unnecessary and unhelpful. On the other hand, Phonegap is a more recognized name, so when Googling for help, Google Phonegap and not Cordova.
- Don't use JQuery: Things like $('#myGreatElement') are slower to execute than document.getElementById('myGreatElement'). Worse, some methods such as .show() and .hide() use inefficient techniques than can cause lags of even 2-3 seconds as opposed to no lag at all.
- Don't use JQuery Mobile: JQuery mobile is slow and bloated. However it does offer one feature on their site where you can "roll your own" jquery mobile using only the features you want. Their handling of swipe, touch, etc. is very good and takes only 4k of code so you may want to use this only.
- Abuse the canvas element: Canvas is very optimized on the modern mobile browsers so use it for anything you may be updating. For example if you have images that you will fade in/out then draw them on a canvas and fade the canvas. There's an even more important reason to use canvas over img: img has a 5 Meg memory limitation in iOS7 webview so your images will start behaving in screwy ways or won't show up if you have too many of them on your page. Canvas does not have this limitation.
- Use setTimeout for UI elements: An eventListener callback function for a UI element typically has a visual cue for the user to know they interacted with the element as well as a functional result. Even if the visual cue is executed first in the code, it may appear delayed to user until the entire function is completed. This can cause delays of 50 or 100ms which sound insignficant but make the difference between a native-feeling quick-responding app and one that feels just a bit laggy. Avoid this problem by putting the functional parts of the listener in a setTimeout. Delays of about 50ms seem to work well in general.
- Use fastclick or touch events: Click events appear delayed on mobile browsers because the browser is waiting to see if you will double-click. Avoid the problem with fastclick or better yet, don't use click events. Touch events give you the option of responding when the user touches the element or (more universally done) when the user releases from the element.
- Use Crosswalk: The android webview up through KitKat (4.4) performs poorly. Crosswalk wraps your app with the latest Chromium Browser. In my tests this can improve performance more than an order of magnitude in some cases. Moreover, regardless of the Android version the user has, you can know this way what the WebUI is. One issue with Crosswalk is that it runs only on Android 4.x devices (which is now more than 80% of Android users).
- Use real devices for testing: It really isn't faster to develop with the emulators than with the real devices, and the debugging tools aren't better with the emulators. Moreover the emulators aren't perfect and some things show up as issues only on the real devices (such as memory issues). It's hard to get the feel for lag on emulators. The Android emulator is especially slow, although if considering it is really is worth your time to set up the Intel HAXM.
- Debug in Chrome/Chromium: Both iOS and Android use webkit so you get your best feedback debugging in a webkit browser. Sorry, Firefox. :-/
- Don't use localStorage or sessionStorage for large amounts of data: There's a 5 meg filesize limit there. You can save files with your app that will either be backed up to the cloud or not (your choice) if you use the file plugin instead.
General Rules of Thumb, HTML5
- Avoid calls to the DOM: Store the element references in arrays instead. It's *much* faster.
- Use variables local to the scope: If you are going to reference a variable outside a function/method more than once, store it in a variable local to the scope. Improves lookup speed.
- Use jsperf.com: Often there is more than one way to solve a problem and you need the one fastest to execute. Don't guess but test using jsperf.com. Also you can find lots of tests there and you may find a test already addressing your speed question.
- Force Hardware Acceleration: use translate3D(0,0,0) and friends in your css for objects that need to move smoothly and respond quickly. Note if you overdo this you can create lag due to memory issues with the GPU.
- Use css transitions: css transitions such as translate, zoom, opacity are very optimized and hardware accelerated. Don't use javascript for these things but set up css animations instead and trigger them with js.
Useful Plugins
You will likely use allof these for even the simplest mobile apps
- Splashscreen:
- inAppBrowser:
- Device:
- FileSystem:
- Media: The html5 audio methods do not work in Phonegap/Cordova
Other Options
- Ludei: I read it performs better than Crosswalk but there are issues with bugs. My tests didn't suggest a great performance improvement so I haven't gone deep with it.
- XDK: This basically wraps up everything Intel thinks you will need to build your apps --- an IDE, emulator, plugins, etc. The emulator isn't even close to emulating what a real device does and I didn't like the editor.
Todo
Other things that should be discussed:
- window.devicePixelRatio and ctx.backingStoreRatio
- this.thing vs. var thing = this.thing
- memory warnings
- don’t use display none...although there are also problems with translate. Maybe opacity?