Development Update – Week of June 13, 2011
We slipped a bit on on our weekly updates so sorry for the lack of updates recently. We’ve been busy prepping for Beta 1 and fixing bugs so there is a lot of activity. Here’s what we’ve been up to on the jQuery Mobile project.
Over the last few weeks, we’ve been deeply re-factoring our Ajax navigation system to make it more extensible and robust. This week, we’re happy to announce that we just landed a batch of improvements to URL handling and base tag manipulation.
Improved URL handling
There are a number of factors involved in loading files in jQuery Mobile. The framework essentially listens for normal link clicks and form submissions and automates them through Ajax instead of regular HTTP, which allows us to support page transitions as the user navigates a site. Path handling within jQuery mobile is one of the most complex parts of the framework because it needs to handle the wide array of paths that a browser may encounter and seamlessly resolve the page and all it’s dependencies (images, stylesheets, scripts, etc) and also needs to work well with file:// URLs for installed applications.
This week’s re-factor now covers all these path types and includes robust unit test coverage to ensure we avoid regressions moving forward.
Base Tag fixes
The Ajax navigation system loads multiple “pages” into the DOM of the starting page. Each of these pages loaded in could live in completely different directories on the server so the paths of links, forms, images, scripts and styles of each page need to be dynamically set so everything “just works”.
To do this, when the initial jQuery Mobile document is loaded, the navigation code checks for an existing base tag, and if one does not exist, the framework injects one and sets its @href to path for the current document.
When the user clicks on a link to load a page, the framework uses Ajax to load the content, then sets the base tag’s @href attribute to the URL of the page it just loaded. It must do this prior to injecting the HTML source into the document so that any relative links or image paths get resolved relative to the new page’s directory path.
There is a twist to this though. The new page could have a @data-url attribute defined, and the value of that attribute should be used as the base for any content related @href and @src attributes. The path used for the base tag could be either the value of a data-url OR the URL used to load the page so we needed to seamlessly support both scenarios.
When upgrading to the forthcoming beta 1, there’s no changes needed to take advantage of these URL and base tag improvements. For developers who have more complex URL scenarios or are using tools like PhoneGap for installed apps, these will be welcome additions.
Please help us test these navigation changes! We’d appreciate getting feedback in the next few days on these important changes so please submit any issues you find into the GitHub tracker. See instructions at the end of this post for dropping in the latest builds from the CDN into your project for testing purposes.
Beta 1: Coming soon
We know many of you are eagerly awaiting the first beta release and we’re happy to announce that we’re very close to this important milestone. The team is targeting a release within the next week and are just waiting for the community to test the latest batch of navigation changes before releasing beta 1.
We are targeting second beta for July and 1.0 later in August. In beta 2, we will be tackling smoother page transitions, page caching and pre-loading and lots of bug and performance tweaks.
Nested lists: A note of caution
When we first created the list views in jQuery Mobile, we added support for nested lists that would automatically create “pages” for each level of the list and link them all together. It was one of those “wow” features that was both elegant semantically and an accelerator for developers.
However, we’ve been seeing some developers use nested lists as a mechanism for building major portions of their sites, including embedded forms and pages of content and we wanted to weigh in on how these can best be used. Over-using nested lists, especially for embedding forms or content views, has a number of drawbacks:
- You have little control over styling, header bar, or other page content in nested lists because the child pages are generated dynamically. You can set the theme of the bar and the title is generated by the name of the node but there is no built-in way to add logos, navigation buttons or other features to the page. To support this, we’d need to include a templating system and that is too heavy for this simple feature. To have full control of each page, use separate pages and link them together.
- Serving the full tree of list nodes results in heavier pages that include views that may never need to be displayed. It’s understandable that devs use nested lists to avoid seeing the Ajax loader on every click but bandwidth and memory are very limited on mobile devices. We recommend building separate HTML documents for each view and taking advantage of the Ajax navigation to pull in pages on demand. We’re planning on adding a feature that will allow you to preload pages which should help developers deliver the most lightweight page possible, then lazy-load commonly accessed pages from there.
- Listviews with a lot of nodes or nested levels can be slow to render and use. In general, more than 100-200 listview nodes can result in slow performance on older or underpowered devices. Nested listviews are even more taxing on a device because the framework needs to parse the list levels and dynamically create pages for each level. We recommend breaking these into separate pages yourself to speed initialization time up considerably.
- From a semantic perspective, nested lists are only appropriate for a limited number of situations. Specifically, presenting hierarchical, drillable lists. A list of email accounts followed by folders for each is a good use of nested lists, but placing richly formatted listviews for each the message lists is definitely overkill and won’t view cleanly in non-enhanced devices.
The nested list feature, although cool, is something we’d like to discourage using because of the drawbacks listed above. In general, we would like to encourage developers to use separate pages instead of nested lists and rely on the Ajax navigation system to pull in nodes as needed. This will always be the most lightweight approach because you’re only serving the minimal amount of markup needed at a given time.
We’ve discussed deprecating this feature at some point in the future because the same effect can be achieved with better performance and extensibility with our standard page model. We’re looking for feedback from the community on how to proceed so chime in below in the comments.
jQuery Mobile tutorials
Jorge Ramon has pulled together a nice Roundup of jQuery Mobile tutorials. Some good reads!
jQuery Mobile weekly team meeting
Join us at our new day and time: Thursdays at 2:00pm EST on #jquery-meeting on freenode.net to listen to the team meeting
Nested lists with same parent text resolve to the same sub-page (issue #1617) – Created a unique ID for each nested list to avoid naming collisions.
Form errors with Ajax disabled – Fixed cases where jqmData(ajax=’false’) might also match forms, which have neither of “src” or “href”. In that case, thisUrl is undefined, and the following replace results in an error. Thanks frietsch!
Get the latest builds on the jQuery CDN
To take advantage of the daily improvements happening in jQuery Mobile, be sure to check out out the new daily and latest builds that are now available on the jQuery CDN for hotlinking. This allows you to upgrade to the latest code without waiting for the next official release.
Here are the three files to include in the head of your page to always be viewing the latest in Git:
<link href="http://code.jquery.com/mobile/latest/jquery.mobile.min.css" rel="stylesheet" type="text/css" /> <script src="http://code.jquery.com/jquery-1.6.1.min.js"></script> <script src="http://code.jquery.com/mobile/latest/jquery.mobile.min.js"></script>
Please keep in mind that this the unstable, development version so we don’t recommend linking to the latest in a production site or app but it’s great for development and testing.