Why I *almost* love jQuery Mobile
The jQuery Mobile project looks to become the holy grail for mobile web developers: the only mobile app framework you need. And I soooooooooooo want it to be. I think lots of people are rooting for the project to live up to its potential. Having used the beta version lately for building some mobile apps, I believe they are coming quite close. Trust me, I want to love jQM, but so far I can’t quite do it.
For a while I was building apps using jQTouch, the original, PastryKit inspired framework from David Kaneda. I really like jQTouch - because it works they way I expect a mobile framework should work. It uses simple markup, straightforward CSS for styling, and simple JS targeted for mobile webKit with fallback event handlers for testing on the desktop.
Unfortunately, once Kaneda went to Sencha to build Sencha Touch, development on jQTouch pretty much stopped. In particular, jQTouch does a good job of emulating the iPhone UI, but doesn’t really have similar support for Android. And so the “favorite open source toolkit for mobile web apps” spot remains unfilled.
Let me just say that jQuery Mobile is an awesome framework. It contains tons of great ideas and sophisticated device support. And where I think it falls short tends to be in areas where I disagree with the approach taken, not in the implementation.
Mobile Apps Don’t Download Their UI
My first beef is the emphasis that jQuery Mobile places on loading app pages via Ajax. The idea here is to make the job of the mobile developer easy by letting them continue to generate their pages on the server. Unfortunately, this is not the way that mobile apps work. Native mobile apps don’t download their UI from a server. They install all their UI code onto the device, and they only download new data from the cloud. And moreover, they cache that data on the device. The result is that the app feels responsive in most cases, even if the wireless connection is slow or down altogether. Think about the native mail or Twitter apps. Lots of pages in the Twitter app show data pulled from the cloud, but the page frame always displays immediately, and then you see a little spinner indicating that more data is being loaded. Contrast this with a typical jQuery Mobile app, where every time you tap a navigable item you see this big overlay spinner while the next page is loaded via Ajax. Over the typical slow wireless connection these delays are really noticeable.
The other issue with Ajax page loads is that oftentimes you are going to pull in a bunch of HTML, plus CSS, JS, and image assets. Sure, theoretically much of this should be cached, but in practice proper caching of all those files is pretty error prone.
I believe a good mobile web app should work like a native app. It downloads all its UI at once, and it only has to go back to the cloud for new data to display. Now this requires more work on the developers part, because you have to build DOM injection code in JS to update your display. However, this is really that hard, and its something lots of developers have become familiar with using JSON apis.
Fortunately, jQuery Mobile supports this style of app. I just wish the framework were more oriented towards it, mostly as a best practices guide for developers.
However, HTML and the web just don’t work that way. Web pages are built with HTML markup, and styled via CSS. This approach is just fundamentally different from the widget approach. So the problem with widget-based mobile web frameworks is that you have to learn some new toolkit. Anything you know about HTML or CSS, or even things like using jQuery selectors, you basically have to throw out the window. Instead you learn all about someone’s custom widget library and how to use their custom API to achieve what you already knew how to do with HTML and CSS.
To its credit, jQuery Mobile takes a “hidden widgets” approach. You actually build you page using regular HTML markup. Then at page load time jQM comes along in the background and “widgetizes” your page. It basically goes and adds elements into the DOM to “draw” the widgets in the library. So generally you don’t have to worry about the widgets or learn their API. Except when you do. For instance, if you add LI elements to a UL list after your page is loaded (such as after an Ajax call for some data), then you have to call the $(elt).listview(‘refresh’) command. Ick. Maybe at some point they will figure out how to do this automagically, but the leaky abstraction that is the mapping from markup to widgets is annoying at present.
The other problem here is that when you go to look at your DOM in the Inspector, it doesn’t look like your original markup. And so when you’re trying to figure out how to style some element, you better go read the jQM docs, because figuring out the CSS selector hierarchy is pretty painful.
Fugly Markup, Too Many Devices
jQM uses some pretty cruddy markup rules. Basically you indicate the widget you want on some element and various attributes by specifying a “data-XX=” attributes on the element, like this:
<div data-role=”page” data-theme=”c”>
You’re thinking “Ewww” right? I understand the motivation here. Those data-XX attributes will be ignored by older browsers, and you’ll be left with simple div -> ul -> li markup that should render somewhat presentably on the device. And if you go read the list of devices supported by jQuery Mobile, you can see they are targeting lots of older browsers. And this I think is where the project made another mistake. By the time jQuery Mobile hits 1.0, most of those phones will be obsolete. The market is very quickly moving to de-facto standardize on modern WebKit as the mobile browser. I mean, god love Firefox mobile, but is anyone really running that on Android Phones? Or put another way, shouldn’t it be up to Mozilla to support HTML5 as well as WebKit, since its playing catch up in the mobile market? But instead jQuery Mobile is expending lots of developer time and energy supporting a bunch of antiquated or truly marginal cases, when what most developers want is something that works great on iPhone and Android, and maybe will work on Windows Phone in a year, or Blackberry *after* it moves to WebKit.
And thus to the markup. If jQuery Mobile was targeting modern browsers only, it could do away with a lot of its ugly markup in favor of really nice HTML markup like this:
<article> …. page content … </article>
<footer><a href=”#home”>Home</a><a href=”#notes”>Notes</a></footer>
Ah…look at that! Wouldn’t you like to write your apps like that?