Hmmm… jQuery Mobile… if only you delivered on mobile the way you promised…. the world’s most popular JS framework sadly misses the mobile mark and by a wide margin. If you do have to use jQM then you’re probably looking for tips on how to get some level of performance out it.
Scroll Performance
This is a widely discussed topic – list view performance in jQM is pretty poor and is most noticibly lacking in Android especially in older devices. Throw in form elements like sliders, buttons – and things are downright unacceptable. Per the aforementioned online discussions and some of my own trial and error remove the following to get a modicum of performance gains:
- Remove all radiused corners
- Remove all gradients – I replace them with tiled backgrounds to achieve the same effect
- Remove all shadows
- “Disable” all hover states – a big performance hog on mobile
- Don’t inset the list view – doing so adds more overhead for the mobile browser / webview
An example that has worked for me – you’ll want to tailor this for your specific needs. This works on the premise that if all of the up, down and hover states’ CSS is the same the browser doesn’t have to redraw anything. The result is that nothing happens and you negate the performance hit that you would have otherwise had to endure.
... *.ui-listview li.ui-btn-up-c, *.ui-listview li.ui-btn-down-c, *.ui-listview li.ui-btn-hover-c, *.ui-listview li div.ui-btn-hover-c { background: #fff !important; font-weight: bold !important; color: #222 !important; background-color: none !important; background-image: none !important; background-image: -webkit-gradient(linear, left top, left bottom, from( #fff ), to( #f1f1f1 )) !important; background-image: -webkit-linear-gradient( #fff , #f1f1f1 ) !important; background-image: -moz-linear-gradient( #fff , #f1f1f1 ) !important; background-image: -ms-linear-gradient( #fff , #f1f1f1 ) !important; background-image: -o-linear-gradient( #fff , #f1f1f1 ) !important; background-image: linear-gradient( #fff , #f1f1f1 ) !important; border-top-style: solid !important; border-top-width: 0px !important; border-top-color: rgb(204, 204, 204) !important; border-bottom-style: solid; border-bottom-width: 1px; border-bottom-color: rgb(204, 204, 204) !important; box-shadow: none !important; } ...
In addition, if you’re using iScroll or iScrollView you’ll want to do the following:
- Set vScrollbar to false – the presence of the scroll bar adds some overhead so remove it from view
And here’s an example of setting some defaults in iScrollView – notice that I reference getDeviceInfo() – see my previous article titled Mobile Device Detection using the UserAgent as the code there is assumed to be in use here. Of course you can use your own platform detection scripts. Anyway, you can see that I only use this setting in Android.
... var _d = myapp.util.getDeviceInfo(); // my own device-detection library if (_d.android){ $.mobile.iscrollview.prototype.options.vScrollbar = false; } ...
Shifty Fixed Headers
Symptoms:
- When clicking the page the headers disappear
- When clicking the page elements within the header or footer shift up or down.
Add the following to your application:
... $("[data-role=header]").fixedtoolbar({ tapToggle: false }); ...
I put the above in the “deviceready” event.
Alternatively you could add the following attribute to your header divs:
... data-tap-toggle="false" ...
Flashing or Slow Page transitions
iOS does a good job with jQM’s page transition animations. Android is another matter. You will want to turn off page transitions entirely for Android.
... $.extend( $.mobile,{ var _d = myapp.util.getDeviceInfo(); // my own device-detection library defaultDialogTransition: (_d.android ? 'none' : 'pop'), defaultPageTransition: (_d.android ? 'none' : 'fade'), }); ...
Manage DOM Bloat
If you have a multi-page app jQM will add each page into the app’s DOM as you navigate the app. The purpose is to “speed up” the app as jQM will no longer have to do any DOM insertion when future page requests happen. That’s all fine and good for desktop computers but it kind of stinks on mobile. The more that is added to the DOM the slower your app gets. Memory use for most apps is a major concern so you definitely want to disabling this, like so:
... $.extend( $.mobile,{ domCache: false }); ...
Another reason to disable is that events like pageload will only fire the very first time the page is inserted into the DOM. Thereafter, it doesn’t fire because the page has already been loaded (cached).