Sunday, February 19, 2012

jQuery Mobile: Performance Tips

sharkDo you know what swimmers wore in the last summer Olympics to gain a performance advantage? They wore sharkskin suits. The swimmers that wore this new technology won more races and broke more world records than ever before. Unfortunately, mobile development requires much more effort than simply sliding on a suit to gain more performance. Mobile developers are challenged with multiple limitations that affect performance: a network with limited bandwidth and underpowered devices. As we build mobile applications, it is important to code review the entire project with an emphasis on performance. Listed below are several tips for improving the performance of your jQuery Mobile applications:


Prefer Native jQuery Mobile Widgets

We can gain several implicit advantages by reusing jQuery Mobile's native widgets. They are compatible across all browsers, they simplify maintenance, and more importantly, they save us from writing additional custom code that adds overhead to our applications. While there will be occasions when we need to build custom widgets, it is important to consider all native solutions prior to choosing a custom alternative. I have seen several instances where custom alternatives were built when native solutions would have provided similar behavior with much less overhead. For instance, I was recently reviewing a jQuery Mobile app that had built a custom message box when the same effect could have been designed with a native inset list (see Figure 1-1).
Native versus Custom Message Box
Figure 1-1. Native versus Custom Message Box


The native solution is significantly leaner containing 80% less CSS versus the custom solution (compare Listing 1-1 versus 1-2).
Listing 1-1. Custom Message Box
<style>
.message-box {
background-color: #ECE8D3;
color: #816d49;
font-size: 0.75em;
line-height: 1.3;
margin: 0 0 10px;
float: left;
width: 100%;
-moz-box-shadow: 0 0px 10px rgba(0, 0, 0, 0.3);
-webkit-box-shadow: 0 0px 10px rgba(0, 0, 0, 0.3);
box-shadow: 0 0px 10px rgba(0, 0, 0, 0.3);
-moz-border-radius: 0.6em;
-webkit-border-radius: 0.6em;
border-radius: 0.6em;
}
.message-box .inner {
padding: 10px 12px;
}
.message-box p {
color: #816d49;
font-size: 11px;
text-shadow: none;
font-weight: normal;
}
</style>

<div data-role="content">
<div class="message-box">
<div class="inner">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna.</p>
</div>
</div>
</div>

Listing 1-2. Native Message Box
<style>
.ui-li-message {
padding-top:10px;
white-space: normal;
}
</style>

<div data-role="content">
<ul data-role="listview" data-inset="true" data-theme="e">
<li>
<p class="ui-li-message">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna.</p>
</li>
</ul>
</div>


Another example I also encountered was the usage of JTSage's SimpleDialog plugin. While I have found value with JTSage's DateBox plugin for configuring date ranges, I have not seen a compelling advantage to consider their SimpleDialog versus the native dialog we get out-of-the-box with jQuery Mobile. Again, the native dialog provides similar behavior with much less overhead.


Removed Unused Themes

If you plan to style your entire jQuery Mobile application with custom themes it is preferred to use the structure-only CSS file from jQuery Mobile's download site. This is a lightweight alternative for applications that do not need the default themes and it simplifies the management of the custom themes (see Listing 1-3).
Listing 1-3. jQuery Mobile's structure file without default themes
<head> 
<meta charset="utf-8">
<title>Custom Theme</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel=stylesheet href="css/theme/custom-theme.css" />
<link rel=stylesheet href="css/structure/jquery.mobile.structure.css"/>

<script type="text/javascript" src="jquery-min.js"></script>
<script type="text/javascript" src="jquery.mobile-min.js"></script>
</head>
Additionally, to reduce HTTP requests, it is preferred to merge both the custom theme and structure files before deploying to a production environment.


Prefetch Secondary Pages that are Accessed Frequently

Most often, it is preferred to leverage the single-page model and dynamically append frequently accessed pages into the DOM in the background. We can achieve this behavior by adding the data-prefetch attribute to any link we want to dynamically preload:
<a href="prefetch.html" data-prefetch>Prefetched Link</a>
This hybrid approach allows us to selectively choose which secondary links we want to dynamically load and cache. This pattern is only recommended for pages that are accessed very frequently because this behavior will trigger an additional HTTP request.


Remove Unused Plugins

The jQuery Mobile framework contains many valuable plugins. However, if your application does not use all features then you can make your app a bit leaner by simply removing the unnecessary plugins. For instance, I was able to save 6KB by simply removing the following plugins from the uncompressed jQuery Mobile library: collapsible, collapsibleset, checkboxradio, select, and slider. The jQuery Mobile team is currently creating a Download Builder that will help simplify this task in the future.


Cache Highly Accessed Read-Only Pages

We can cache jQuery Mobile pages by attaching the data-dom-cache="true" attribute on the page container:
<div data-role="page" data-dom-cache="true">
The cached pages are persisted in the DOM. While this feature is advantageous for frequently-accessed, lightweight pages, its usage needs to be monitored carefully to assert the DOM remains at a manageable size.


Prefer the CDN-hosted minified and gzipped jQuery Mobile files

The files from the jQuery Mobile's CDNs are highly optimized and will provide a more responsive experience for your users. They are compressed, cached, minified, and can be loaded in parallel.


Mobile Web Performance Analysis Tools

If you are interested in evaluating your own mobile sites, here are several popular analysis tools that offer something unique in regards to how they grade for performance:
  • YSlow for Mobile: A Bookmarklet that grades internal and external sites from either a mobile or desktop browser.
  • Blaze: Evaluates the performance of your site from a physical device that is running in the cloud. This tool only allows you to evaluate external sites.
  • pkapperf: Captures performance metrics from your device's physical network traffic. This tool allows you to evaluate both internal and external sites.


Faster mobile networks and mobile CPU's will eventually become our shark skinned suits and mobile sites will become faster without any additional effort. While this is promising for developers, the Olympic swimmers are facing a new challenge. Those famous shark suits have been banned for the 2012 Summer Olympics.