Ruggedizing Mobile Applications

By Matthew Seeley on 09 03 2014

Mobile environments can be hard on developers. There are a laundry list of constraints to deal with, everything from smaller screen sizes and slower processors, flaky unreliable intermittent connectivity to the internet, to the completely nonstandard browsers and unique native development environments that many vendors ship on the 6+ different common mobile operating systems across the world.

It's enough to take any application and make it look dysfunctional.

This is often highlighted personally for me as a developer because web applications are a significant part of my life. Most of my work and play is based around applications that depend on an internet connection, such as Gmail, Evernote, Skype, SpiderOak, GoG, and many more.

As a recent experiment, I've been living a "nomadic" digital life. I have been relying solely on a Clearwire WiMax modem when at home, and tethered cellular data service when elsewhere. And my experience with these services has changed my evaluation of the importance of robustness in web development.

Applications often make assumptions about their users internet connections. While most developers are mindful of the different connection speeds, we may assume users have relatively low latency (mobile hotspots or satellite connections can have 100 to 2,000+ ms latency). Even assumptions about our markup may not always hold true (shady network operators will sometimes inject elements into your applications HTML markup to notify users of data caps, overages, display advertisements, ect)

Lucky for us, their are a few simple tips we can use to enhance our web applications for these uncertain, ever-changing environments. These won't solve the problems mentioned above, but can help reduce the chance they will interfere with your application.

Offset and Background Network Usage

In a mobile environment, your most reliable network connection will usually happen on the device while driving, or while outdoors, especially for users on smaller or weaker network providers. Unfortunately, most people typically interact with their phones during their most unreliable network states (while indoors, at an event, or underground while parked in a parking structure). How do you handle the consistent attack on your network state?

Offload network requests to the background.

For example, if you are writing a Twitter client, pull in all tweets, notifications, and direct messages in the background. Queue up tweet requests. Writing an e-mail client? Download messages in the background, queue read state changes, label changes, and sent messages.

By offloading network requests to either before or after your application is used, you can greatly improve the perception of the quality and responsiveness of your application.

Compress requests.

Compression brings an important tradeoff between CPU time and bandwidth time, and on larger files, its important to investigate the tradeoff for best performance. But on mobile and web applications, it's almost always favorable to save bandwidth at the expense of CPU, especially when dealing with small amounts of data (such as the HTML, CSS, and images returned on a typical web request).

If you are using Apache, much of this can be achieved by setting up mod_deflate appropriately, using the configuration to include files that can benefit from compression, and exclude those that won't (such as PNG or JPEG images, as they should already be compressed)

Reduce requests

While shrinking down the size of your application elements will help with page loads, each request carries its own overhead. Reducing the number of requests eliminates that overhead on each request removed.

One easy way to accomplish this is by combining resources. For instance, you can combine multiple javascript or stylesheets into one file, so that a web browser needs only make a single request for the resources. (And you need not do this by hand, Rails and many other web frameworks have this functionality already built in.)

Aggressively Cache

Even better than reducing the size and amount of files, is eliminating their calls altogether! Aggressively cache resources that aren't likely to change often. For a web application, this might include javascript libraries or CSS.
For a native mobile application, this can be any data that holds value for more than a specific moment. For example, in a Twitter client this data might include a user's avatar or profile information. This data can be loaded once, held on to for a long while, and has a low likelihood of changing often.

Test the worst cases

Mobile internet access has a myriad of problems that often occur. But most developers have nice, luxurious development environments with internet access that is usually very quick and reliable.

The best way to ensure your application is making the most of it's internet resources is to force these bad environments during testing. One way to accomplish this, is by using a "Chaos Monkey" philosophy for testing. Chaos Monkey is the name of a tool that Netflix uses to test Netflix's fault tolerance by randomly terminating Amazon AWS instances.

While this software might not be directly applicable to mobile applications, the philosophy is. Test your applications in environments where internet access is randomly cut off, or otherwise hangs for many seconds at a time, to help ensure your application accounts for the various states that lack of internet access can create.

Measure twice. Regardless of the cut

Of all the topics just mentioned, by far the most important of these is your metrics.

While all of the above are usually good suggestions, they may not be appropriate for all projects. If you are ever in doubt about the benefits of a particular strategy, test it! Tools such as Firebug + YSlow, or Chrome Inspector + Page Speed can assist you in benchmarking these changes in web applications, so that you know if a particularly strategy offers a performance benefit, and by exactly how much.

One added benefit of these changes is that none of these are exclusive to mobile apps -- improvements made in these areas benefit all users, even those with power devices or fast reliable internet access.

Many developers are already familiar with most, if not all of the tips above. We all know that we should be doing many of the suggestions above. But living a nomadic internet existence has really helped me empathize with users who have to live with service like this 24/7. The experience has really impressed upon me the importance of why we should be following these practices.