Mobile development with HTML5

###HTML5: the standard, the buzzword and the legend If you read blogs that are even slightly related to tech, you likely hear about HTML5 on a near-weekly basis. Although the new web standard does not do your laundry, it has features that enable the creation of powerful applications—using only HTML, CSS and JavaScript (a Rails back-end can bring additional firepower to the table). This post will go over some key concepts and features of HTML5, setting the stage for more advanced subjects. ###Browser Compatibility Perhaps the biggest pain in developing a web-based application is ensuring that your application is compatible with the various browsers in use today. Fortunately, this is less of a problem in the mobile world. Because people get new phones more often than new computers and because the smart phone space is relatively young, there are simply fewer old smart phones out in the wild. However, this is not a carte blanche; you should test your site with any devices you wish to support, not just simulators. ###Viewport When you visit a website not designed for mobile browsers, it first appears very zoomed out. This is done intentionally by the mobile browsers to make the website viewable. They set the default viewport width to between 800 and 980 pixels (depending on the browser). This allows the user to view the whole website and then zoom in as needed. However, if you are crafting a website specifically for mobile, it make sense to set the initial viewport for the mobile device. This is accomplished with the viewport meta tag.

<meta name="viewport" content = "width=device-width">

This sizes the viewport to the device’s width, so the content does not initially appear zoomed out. You will likely want to disable zooming entirely, so the user doesn’t accidentally zoom out and distort the UI. Do this by setting user-scalable to no.

<meta name="viewport" content = "width=device-width ,  user-scalable=no">

Some sites currently hard-code the width of the viewport to 320. Why? Because this is the width of the iPhone. However, in general, it is a better practice to use “device-width” instead of 320.

Having your site correctly sized for mobile is nice but the next two features of HTML5, caching with the cache manifest and local storage, allow for fully functional offline sites. ###HTML5 Caching HTML5 caching allows users to view websites they have visited before without a connection to the web. Not only is this extremely useful for users who may not get coverage where they want to use the application, but it can also mitigate brief drops in a connection.

To setup HTML5 caching, you add a manifest file to the html tag of every page you want to cache.

<html manifest="/cache.manifest">

This file starts with “CACHE MANIFEST” and then enumerates the files that the application should cache.

CACHE MANIFEST
/mystyle.css
/scripts.js
/logo.jpg

Now those files will be available offline. Frankly, there is a long list of gotchas with the cache manifest. I review some key ones below but suggest reading Dive into HTML5 for all the details.

The first and foremost, your site will default to cached files over recently downloaded ones, meaning that even if the cache has changed since the browser has last visited the page, the browser displays the old pages until the page is refreshed (or told with JavaScript to update). This is further compounded by the fact that most web servers tell the browser cache the files they serve. When you are developing your site, be sure to tell your web server not to cache the cache manifest, so you always download the most recent copy.

The next big gotcha is how the browser manages the downloading process. If the browser detects that the manifest has changed, it re-downloads every single file. Not only does this make the process expensive, if a single file fails to download correctly, the browser abandons the update and loads the previous cache. When this happens the browser does not post any error by default. However, you can use JavaScript to detect the error thrown by the manifest.

$(function() {
  $(window.applicationCache).bind("error", function() {
    alert("Cache: update failed");
  });
});

So now your site is cached and everything worked. You’re ready to launch? Not really. This caching technique works well with static content. However, if your application has content that is dynamically created and frequently changed (most web apps), it will not work well. This is because, unless the cache is changed, the old html page will be displayed, not the page with your new content. The simple answer is to change the cache manifest file whenever new content is added. However, this is generally not a good idea because it forces the browser to re-download every file every time any content is changed—very costly if your content is updated frequently. The solution is to use jQuery templates to build the page dynamically. ###jQuery Templates The best practice is to populate your content through JavaScript templates. In this way, the content is not part of the HTML page and thus is not cached with the cache manifest. For this, you need to download and add jQuery and the jQuery template plugin to your application.

There are three steps to using these templates:

  1. Define the template.
  2. Define the collection.
  3. Tell jQuery to populate to the page with the template.

Below is an example for a simple blog application.

  1. Define the template:

  2. Define the collection (of posts in JSON).

  3. Tell jQueryto populate to the page with the template.

Although this content is loaded via JavaScript, it is not dynamic—it is just defined on the page. For dynamic content we will want to use JSON provided by the server. Let’s assume our blog application provides us with the JSON representation of our blog at this URL:

/posts.json

We will tell jQueryto make a request for the JSON and then use it to populate the page.

<script type="text/javascript">
$.getJSON('/posts.json', function(data) {
$( "#post_template" ).tmpl( data ).appendTo( "#blog_posts" );
});
</script>

We also need to change the template so that it can handle the JSON elements, substituting post.name for Name and post.body for Post:

<script id="post_template" type="text/html">
<div>
  ## ${post.name}
  ${post.body}
</div>
</script>

Now our blog is pulling content that is not cached in the cache manifest and using jQuery templates to populate the page. However, this works only if our mobile browser can connect to our server. This feels like two steps forward and three steps back, but trust me, we almost have a working mobile HTML5 app. We just need to include one last component of HTML5, Local Storage. ###Local Storage Christopher Haupt of Webvanta recently authored a guest blog post about Local Storage. See the Enhancing Client-side Storage with HTML5 post for details and general use.

On a high level, Local Storage is a client-side key-value store implemented by the browser. It stores strings of text locally and then recalls them later. Here, we use it to store JSON so we can populate the blog with posts even if there is no connection to the server.

Although we could write this by hand, there is a great plugin to manage the process for us. The jQuery Offline plugin uses content from Local Storage if the server is not available and will store fresh content in local storage when it’s received.

Download this plugin from jQuery-Offline

To use the plugin we change the getJSON call to retrieveJSON. We will also need to change our script slightly as there is one key difference between getJSON and retrieveJSON. The latter will execute twice, once to pull from the cache and again to get the new content from the server. This will cause the posts to appear twice if we simply append the new posts to the page.

<script type="text/javascript">
$.retrieveJSON('/posts.json', function(data) {
$( "#blog_posts" ).html($( "#post_template" ).tmpl( data ));

});
</script>

The blog application can now be viewed offline and is correctly sized for a mobile browser! You can download this example here offline-blog.

I hope you enjoyed this initial look at some of the technologies that are making mobile development easier. In the coming weeks I hope to be covering more advanced topics such as the popular MVC framework Backbone.js.