MOBILE

Programming the Mobile Web : Performance Optimization

2/15/2011 11:36:32 AM
Performance is the key to mobile web success. People want high-performance websites. We hate to wait on our desktops, and the situation is far worse on mobile devices, with their constrained resources. I will just try to distill some best practices and share some hacks that you can easily apply to enhance your website’s performance.

Performance has recently become a hot topic in the desktop web world. In general mobile web developers should follow the same practices, but there are some new ones to keep in mind as well, and some desktop web best practices that will not work on these devices.


Mobile browsers aren’t the same as desktop web browsers, and not all mobile browsers are created equal. Specifically, the quantity of resources that can be downloaded in parallel and the cache functionality differ. Nevertheless, it is better to approach mobile performance optimization from here than from the ground.

Note:

If you want to know more about high-performance mobile websites and mobile browser behavior, check out http://www.mobilexweb.com/go/performance.


1. Measurement

The first thing we need to do is to measure. If we cannot measure, we cannot optimize. However, measuring mobile websites is not easy. Typical desktop measurement and profiling tools don’t work for mobile devices, and HTTP sniffers are difficult to implement for mobile browsers.


Note:

Nokia provides a free tool for profiling the battery energy used by an application. You can download the Nokia Energy Profiler for free from http://forum.nokia.com.


Advanced memory and process profiling for JavaScript is still more of a dream than a reality. However, Yahoo! has created a simple JavaScript profiler called the Yahoo! UI Profiler, available at http://developer.yahoo.com/yui/profiler, that will work on any A-grade browser (Symbian, iPhone, Android), and you can always use new Date().getMilliseconds() to get the time differences between two moments in your JavaScript code.

If you are using an emulator or a real device with WiFi capabilities, you can use any HTTP sniffer proxy, configuring the emulator and your device with your desktop IP address and port as the proxy for navigation. There are dozens of tools for doing this, but the one I like best is called the Charles Web Debugging Proxy. A full-featured free trial for Windows, Mac, and Linux is available at http://www.charlesproxy.com.

Once you’ve installed it, you can use the proxy (by default on port 8888) in your mobile emulator or device, and you will see every request, including the headers and the order and simultaneity of requests made on each browser to optimize the final download time for resources. You can also see Ajax requests with JSON and XML browser support.

If you have a dedicated server (or even your own development computer with full inbound access to port 80), you can install one of these proxies and a web server and browse your website from any phone on any network to analyze how is it rendering and requesting resources.

Nokia emulators (Series 40 and Symbian) also have a great network sniffer that enables you to see all the requests that the browser is making, including the headers.

2. Best Practices

Here are some global best practices you should always have in mind:

  • Keep it simple.

  • Reduce the HTTP requests to the minimum possible.

  • Implement Ajax requests if you can, and if the device supports them.

  • Make the cache your friend.


Warning:

HTTP request headers are generally larger in mobile websites because of the large User-Agent, Accept, and other headers. Remember that these headers are sent with each and every request your page makes. That is why it is important to keep the number of requests to the minimum.


2.1. Reducing requests

There are plenty of tips for reducing network requests:

  • Use only one CSS and JavaScript external link per page.

  • If the script and/or CSS is only for one document, don’t use external code; instead, embed it in the page.

  • Use inline images whenever you can.

  • Use CSS Sprites.

  • Reduce the use of images for effects, titles, and text. Try to meet all of these needs using only CSS.

  • Use multipart documents when compatible.

  • Download only the initially required code and resources and then, after the onload event, download all the rest on Ajax devices (lazy loading).


Note:

Every mobile browser supports a cache for resources and you should definitely use it, with a long-lived expiry for each static resource. Analyze how the cache works (this is outside the scope of this book) and make it your friend, not your enemy!


2.2. Compressing

Compression is a necessity, and there are different techniques you can use for it:

  • Minimize your XHTML files, removing spaces, comments, and non-useful tags.

  • Minimize your CSS files, removing spaces and comments.

  • Minimize your JavaScript files, removing spaces and comments and obfuscating the code.

  • Use HTTP 1.1 compression for delivering static and dynamic text-based files (XHTML, JavaScript, CSS, XML, JSON).

  • Use a cookie-free domain (or alias domain) for static content files.

For minimizing files, there are plenty of online and offline tools, like JSMin (http://crockford.com/javascript/jsmin) and YUI! Compressor (http://developer.yahoo.com/yui/compressor).

Going Beyond JavaScript Compression

There are plenty of good JavaScript obfuscators and minimizing tools out there, but Google has taken an extra step and created Closure Compiler, a new concept in JavaScript programming. It is not just a minimizing and obfuscating tool, but it is also a compiler: it compiles JavaScript code into better JavaScript code and it is very helpful for mobile websites.

You can download the compiler at http://code.google.com/closure/compiler or use the web application compiler at http://closure-compiler.appspot.com.

The code will be rewritten to be lighter and quicker to execute. The resulting code will not be suitable for human reading because it will not use good programming practices, but that is not the goal. We are not going to edit the resulting code; we will always work with the original code (with comments and all the best practices) and recompile it before sending it to the server.


2.3. HTTP compression

HTTP 1.1 added compression (using GZIP and deflate) as an optional possibility when delivering a file to the client. Using this option is strongly recommended for text-based files on most mobile devices, because it will reduce the traffic between the server and the client by up to 80%. It will add some overhead on the client (to uncompress the content), but it’s well worth it. Network traffic will be one of our worst problems if the user is not connected to a WiFi network. Even with 3G connections, the network can have latency problems.


Note:

If you work with ASP.NET Web Forms, you should be careful about the usage of the ViewState, which generates big hidden input tags in the HTML. Deactivate the ViewState on the controls where you won’t use it.


You will find plenty of resources on the Web about how to configure HTTP compression for Apache, Internet Information Server, and other products. The most important thing you need to remember is to also compress dynamic scripts delivering markup, like PHP scripts, which by default do not use HTTP compression in Apache.

2.4. Other tips

Here are some other tips to keep in mind:

  • Compress images and choose the best format and color palette. You can use the free online tool Smush.it from Yahoo!, available at http://www.smushit.com.

  • Deliver small images for small screens. You can use a dynamic resizing tool, or the free online service at http://www.tinysrc.net.

  • Keep files under 25k because, if not, they will have problems to be cached on some devices.

  • Reduce the initial load time as much as possible. You want the web application to be ready as soon as possible.

  • Minimize DOM access and simplify your document structure.

  • Use HTML 5 storage for caching data and resources in base64.

  • Flush the buffer early, using flush() in PHP or Response.Flush() in ASP.NET, after </header> and after big blocks of visual components.

  • Avoid redirects between pages, especially in the home page.

  • Create a quick and simple home page.

  • Put script tags at the bottom to avoid resource download delays.

  • Use a content delivery network or a static server for static content if you have a lot of images or other static content.

  • Remove any non-useful headers from the server responses (like server identification or “powered by”).

Deferred JavaScript Evaluation

The Gmail team, in conjunction with Charles Jolley (http://blog.sproutcore.com), has created a very clever and simple way of reducing the initial payload time of JavaScript execution. The solution is to deliver the JavaScript code inside a comment block (/* */). This means the JavaScript isn’t executing while loading, and it doesn’t freeze the UI or block other resources.

When you need to execute that library or code, you just get the script by ID, get its content, remove the comment characters, and make an eval of that code. Pretty smart, isn’t it? On iPhone OS 2.2, 200 KB of JavaScript code adds 2.6 seconds to the initial page load time, while if it is comment it adds just 240 ms. After all the initial loading is done (or later, whenever you need it) you can parse it.


2.5. JavaScript performance

Again, keep your code simple. Here are some other specific tips for mobile JavaScript coding:

  • Don’t use try/catch expressions for expensive code.

  • Avoid using eval, even in situations where you might not think about it being used, like when using a string in setTimeout instead of a function.

  • Avoid using with.

  • Minimize the usage of global variables.

  • Minimize the number of changes in the DOM, and make the changes in the same operation. Many browsers repaint the whole screen on each change.

  • Implement a timeout for Ajax calls.

  • Compress (and if you want, compile with Closure Compiler) your code.

You can find an excellent article about JavaScript performance tips for mobile browsers at http://wiki.forum.nokia.com/index.php/JavaScript_Performance_Best_Practices.

Other  
  •  Programming the Mobile Web : Testing and Debugging (part 3) - Client-Side Debugging
  •  Programming the Mobile Web : Testing and Debugging (part 2) - Server-Side Debugging & Markup Debugging
  •  Programming the Mobile Web : Testing and Debugging (part 1) - Remote Labs
  •  Windows Phone 7 : Working with Controls and Themes - Adding Transition Effects
  •  Windows Phone 7 : Working with Controls and Themes - Understanding Frame and Page Navigation
  •  Windows Phone 7 : Working with Controls and Themes - Panorama and Pivot Controls
  •  Programming the Mobile Web : Widgets and Offline Webapps - Platforms (part 5) - Windows Mobile & BlackBerry
  •  Programming the Mobile Web : Widgets and Offline Webapps - Platforms (part 4) - Windows Mobile & BlackBerry
  •  Programming the Mobile Web : Widgets and Offline Webapps - Platforms (part 3) - webOS & Android
  •  Programming the Mobile Web : Widgets and Offline Webapps - Platforms (part 2) - iPhone, iPod, and iPad
  •  Programming the Mobile Web : Widgets and Offline Webapps - Platforms (part 1) - Symbian/Nokia
  •  Programming the Mobile Web : Widgets and Offline Webapps - Standards
  •  Mobile Application Security : BlackBerry Security - Networking
  •  Mobile Application Security : BlackBerry Security - Local Data Storage
  •  Themes on Windows Phone 7 Devices (part 2) - Changing the Theme & Detecting the Currently Selected Theme
  •  Themes on Windows Phone 7 Devices (part 1) - Applying a Theme
  •  Programming the Mobile Web : Mobile Widget Platforms
  •  Programming the Mobile Web : Geolocation and Maps - Showing a Map
  •  Mobile Application Security - BlackBerry Security - Permissions and User Controls (part 2)
  •  Mobile Application Security - BlackBerry Security - Permissions and User Controls (part 1) - RIM Controlled APIs
  •  
    Top 10
    Microsoft Surface RT - The Most Stylish Windows RT Tablet So Far
    Ultrabooks Supertest - The Second Coming (Part 2) : Toshiba Portégé Z930-10X, Acer Aspire TimelineUltra M5-581TG
    Ultrabooks Supertest - The Second Coming (Part 1) : Sony Vaio T SVT1311W1E, HP Envy 6-1006sa Sleekbook, Lenovo IdeaPad U310
    Sony Xperia Tablet S
    The Great In-App Purchase Rip-Off (Part 2)
    The Great In-App Purchase Rip-Off (Part 1)
    You Can Master RAW (Part 4)
    You Can Master RAW (Part 3)
    You Can Master RAW (Part 2)
    You Can Master RAW (Part 1)
    Most View
    iPhone Application Development : Making Multivalue Choices with Pickers - Using Date Pickers (part 2) - Adding a Date Picker
    The HP Virtual Server Environment : nPartitions (Electrically Isolated Hardware Partitions)
    Building Custom Players with the Silverlight Media Framework
    One For All And All In One (Part 3) - HP OMNI 27-1015T, Sony Vaio L Series (Model SVL24116FXB)
    Active Directory Domain Services 2008 : Enable a Group Policy Object Link, Enforce a Group Policy Object Link, Remove the Enforcement of a Group Policy Object Link
    Web Security : Attacking AJAX - Intercepting and Modifying Server Responses, Subverting AJAX with Injected Data
    Create Your Own E-Books (Part 5) - Format Wars, Format Conversion & Apple Steps Forward
    Administering COM+ Security (part 2) - Assessing and Assigning Role Scope, Managing COM+ Security
    Web Blocking
    Cookie D'oh, I Scream
    Samsung Galaxy Camera Review – Part1
    Windows 7 : Protecting Your Computer While Browsing (part 5)
    Migrating to Active Directory in Windows Server 2003 (part 1) - Moving from Windows NT Domains
    SQL Server 2005 : Using Excel (part 2) - Using PivotTables and Charts in Applications and Web Pages
    Windows Vista : Recovering Systems (part 2) - Dealing with startup instability
    Advanced ASP.NET : The Entity Framework (part 3) - Handling Errors & Navigating Relationships
    Installing HP-UX : Software Distributor Background
    A New Lick Of CSS For Old Websites
    Silverlight : Binding Across Elements
    .NET Compact Framework 3.5 : Examining ADO.NET