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).
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”).
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.