I thought this seemed like a timely post given Keynote’s new report showing that 64% of smartphone users expect sites to load in 4 seconds or less. This finding isn’t a total surprise. Previous studies have shown that people expect sites to load at least as fast on their mobile devices as they do on their desktops. But it’s still a wake-up call for any site owner who may have lapsed into a bit of complacency. (And given the fact that it’s August, we’re probably all a little guilty of lapsing into late-summer complacency.)
As you may already know, about 80% of the time it takes to display a typical web page is shared between performing client-side processing and loading resources like stylesheets, script files, and images. So the three main strategies for improving performance — for both mobile and desktop visitors — are to:
- Reduce the number of HTTP requests required to fetch the resources for each page.
- Reduce the size of the payload needed to fulfill each request.
- Optimize client-side processing priorities and script execution efficiency.
As you probably also know, mobile users face unique performance challenges when it comes to implementing the strategies above. These challenges include:
- Slower networks (which is why reducing requests and payload is important)
- Mobile browsers are slower to parse HTML and slower to execute JavaScript (so optimizing client-side processing is crucial)
- Mobile browser caches are much smaller than those of desktop browsers (requiring new approaches to leveraging local storage of reusable resources)
There are a number of fundamental and advanced tactics that you can use to take on these challenges and win. I’m going to give an overview of each one here, but to get more insight and specific how-to details, I urge you to download Strangeloop’s whitepaper on mobile website optimization.
REDUCE REQUESTS
1. Consolidate resources
By now, this is a standard practice, so I’m not going to explain it here, but I want to point out that resource consolidation can be a double-edged sword for mobile browsers. Reducing requests speeds up page load the first time, but larger consolidated resources may not be cached efficiently. So if you’re using this technique, make sure to balance it with techniques to optimize local storage (coming up next).
2. Use browser caching and localStorage
Caching is an essential technique for achieving acceptable performance, but desktop and mobile caches are not created equal. Mobile browser caches are usually much smaller than on desktop machines, causing items to be flushed quickly, so traditional browser caching doesn’t work well for mobile devices. Luckily, the HTML5 Web Storage specification, which has been implemented in all major desktop and mobile browsers, provides a great alternative to relying solely on browser caching.
3. Embed resources in HTML for first-time use
If a resource doesn’t have a high likelihood of already being cached (such as in a mobile context), it is often best to embed that resource in the page’s HTML — a technique called “inlining” — rather than storing it externally and linking to it.
The disadvantage of inlining is that page size can become very large, so it’s crucial for a web application that uses this strategy to be able to track when the resource is needed and when it is already cached on the client. In addition, the application must generate code to store the resource on the client after sending it inline the first time. For this reason, using HTML5 localStorage on mobile devices (as described above) is a great companion to inlining.
4. Use HTML5 server-sent events
The HTML5 EventSource object and Server-Sent events enable JavaScript code in the browser to open a much more efficient channel from the server to the browser, which the server can then use to send data as it becomes available, eliminating the HTTP overhead of creating multiple polling requests.
5. Eliminate redirects
When users try to navigate to a standard desktop site from a mobile device, this often generates an extra round trip to the client and back to the mobile site, consuming several hundred milliseconds over mobile networks. For obvious reasons, it’s faster to deliver the mobile web page directly in response to the original request, rather than delivering a redirect message that then requests the mobile page. And as a courtesy to users who prefer to view the desktop site on their mobile device, you can provide a link on the mobile site that signals your application to suppress this behavior.
REDUCE PAYLOADS
6. Compression and minification
Compression and minification are core best practices. Compression technologies such as gzip reduce payloads; text-based responses, including HTML, XML, JSON, JavaScript, and CSS, can all be reduced in size by as much as 70%. Minification, which is usually applied only to scripts and stylesheets, eliminates inessential characters such as spaces, newline characters, and comments; minified files are reduced by about 20%, on average.
Minification not only reduces bandwidth consumption and latency, but also may mean the difference between a cacheable object and one that is too big for the cache on a particular mobile device. Gzip compression is no help in this regard, because objects aren’t cached by the browser until after they’ve been decompressed.
7. Resize images
Images are one of the single greatest performance culprits. On mobile devices, high-res images are a massive waste of bandwidth, processing time, and cache space. To speed up page rendering and reduce bandwidth and memory consumption, dynamically resize images in your application, or replace images with smaller versions for mobile sites. Don’t waste bandwidth by relying on the browser to scale a high-resolution image into a smaller width and height.
Another option is to load a very low resolution version of an image initially to get the page up as quickly as possible, and then replace that with a higher-resolution version on the onload or ready event, after the user has had a chance to begin interacting with the page.
8. Simplify pages with HTML5 and CSS 3.0
The HTML5 specification includes new structural elements, such as header, nav, article, and footer. Using these semantic elements yields a simpler and more efficiently parsed page than using generic nested div and span tags. A simpler page is smaller and loads faster, and a simpler document object model (DOM) means faster JavaScript execution. The new tags are quickly being adopted in new browser versions, including mobile browsers. Maximiliano Firtman has created an excellent table that shows which HTML5 features are supported by which desktop and mobile browsers.
Similarly, new CSS 3.0 features can help create lightweight pages by providing built-in support for things like gradients, rounded borders, shadows, animations, transitions and other graphical effects that previously required you to load images.
OPTIMIZE CLIENT-SIDE PROCESSING
9. Defer rendering HTML
On mobile devices, attempting to load and render a page with lots of HTML can be slower than loading the HTML first and then rendering it. One approach is to enclose the HTML in a comment tag and then to use JavaScript to remove the comment, load the DOM, and render the page.
You can also assure that the user sees the page quicker by delaying the loading and rendering any content that is “below the fold” of the initially visible area. To eliminate the need to reflow content after the remainder of the page is loaded, replace images initially with placeholder img tags that specify the correct height and width.
10. Defer loading and executing scripts
Parsing JavaScript can take up to 100 milliseconds per KB of code on some mobile devices. Many script libraries (such as scripts that support interactive user behaviour, e.g. drag and drop) aren’t needed until after a page has finished rendering. Downloading and parsing these scripts can be deferred until after the onload event. The same logic applies to script execution. Defer as much as possible until after onload.
The script to defer could be your own or scripts from third parties. Poorly optimized script for ads, social media widgets, or analytics support can block a page from rendering, sometimes adding precious seconds to load times. You’ll also want to carefully evaluate the use of large script frameworks like jQuery for mobile sites, especially if you are only using a couple of objects in the framework.
11. Use Ajax for progressive enhancement
Asynchronous JavaScript with XML (AJAX) is a technique for using the XmlHttpRequest object to fetch data from a web server without refreshing the page where the code is running. AJAX allows a page to display updated data in a section of a page without reconstructing the entire page. This can enable your application to load a bare-bones version of a page quickly, and then to fill in more detailed content while the user is already viewing the page.
AJAX responses benefit from many of the same optimization techniques recommended for standard responses: cache headers, minification, gzip compression, resource consolidation, etc.
12. Implement smart preloading that adapts to the type of network connection
Some techniques should be used only when combined with code to detect the type of mobile connection. For example, preloading resources in anticipation of future requests is smart, but it may not be a responsible strategy if (1) the user’s bandwidth is metered and (2) some of those resources may never be needed.
On Android 2.2+, the navigator.connection.type property returns values that allow you to differentiate WiFi from 2G/3G/4G connections. On Blackberry, you can check the value of blackberry.network to get similar information. In addition, server-side detection of User-Agent header data or other information embedded in requests can alert your application to the type of connection in use.
13. Use HTML5 Web Workers for multi-threading
The Web Worker specification in HTML5 introduces multi-threaded concurrent execution to the world of JavaScript programming. For improving the performance of mobile sites, Web Worker code can be valuable for preloading resources that a user is likely to need to complete future actions, especially when the user’s bandwidth isn’t metered. Using multi-threaded code that employs Web Worker objects (and possibly localStorage to cache the data), operations that preload resources can execute on a separate thread without affecting UI performance.
14. Replace click events with touch events
On touchscreen devices, the onclick event doesn’t fire immediately when a user taps the screen. Instead, the device waits up to half a second (300 milliseconds on most devices), giving the user a chance to initiate some other gesture instead of a click. This delay can significantly impede the responsive performance that users expect. To fix this, use the touchend event instead. That event fires immediately when the user taps the screen.
You may still want to handle the onclick event to ensure that the browser changes the appearance of the button to show a clicked state, and to support browsers that don’t handle touch events. To avoid duplicate code execution when both touchend and onclick code fire, add a click event handler that calls preventDefault and stopPropagation if the click was the result of a user tap that was already handled by touchend.
15. Support the SPDY protocol
Some of the performance bottlenecks that afflict web sites, whether desktop or mobile, result from inefficiencies in the application-layer HTTP and HTTPS protocols. In 2009, Google began work on an alternative protocol named SPDY that addresses some of these limitations. As web servers are released that implement SPDY, your site will be able to use this protocol for any user with a browser that supports it. Google’s SPDY testing reports improvements between 27% and 60%.
As I mentioned above, this is a pretty high-level overview of these mobile-boosting strategies. If you’re looking for more background, as well as how-to information, check out Strangeloop’s mobile optimization whitepaper.
Joshua Bixby is president of Strangeloop, which provides website acceleration solutions to companies like eBay/PayPal, Visa, Petco, Wine.com, and O’Reilly Media. Joshua also maintains the blog Web Performance Today, which explores issues and ideas about site speed, user behavior, and website optimization.