There’s little doubt 2012 was a big year for Real User Measurement, with more and more companies using, advocating or offering RUM solutions. With these new solutions comes a better understanding of the complex world our websites live in. RUM usually shows load times that are double or more what synthetic tests indicated, average load times mean very little, and load times differ dramatically between different situations. Put simply – it’s complicated…
Unfortunately, our optimizations have not yet evolved to handle this new granularity. Almost without fail, current optimization best practices are defined as one-size-fits-all, speaking in black and white terms about what you should do, and offering little situation-specific advice. The primary optimization advice we get out of our rich RUM data is “you’re not as fast as you think – try harder”.
In this post, I’d like to dig into what I see as the next frontier for optimization techniques – Situational Performance Optimization. I’ll offer some insight into what’s available today, and point out some areas we – as a community – should work on improving.
Situational Performance Optimization
Let’s start by defining what is a Situation.
A situation means a specific interaction between client and server – more specifically, each case where a browser loads a web page. Every situation is unique in many ways including the structure of the website being browsed, the browser’s cache state, and the current network conditions.
The goal of Situational Performance Optimization is to make our optimizations aware of this context, and tune the page for each situation. Since we already have the measurement tools in place (through the RUM solutions), what we’re missing are the best practices and the tools.
The best practices are needed to tell us which situations we should care about, and what should we do about them. They can tell us, for example, not to use domain sharding for Android browsers, or to serve lower quality images when the latency is high.
The tools are required to help achieve those things with a reasonable cost. Most websites today serve a single version of the HTML to all clients (with the common exception of redirecting smartphones to a mobile site), and don’t bubble network conditions to the application layer. We need tools that at least provide situational awareness to the code generating the page, and at most perform the actual optimization, reducing the level of expertise required of the developers.
So Many Situations, So Little Time
Clearly we can’t enumerate every possible variable, but we can try to identify the primary ones. Below is a list of common traits that can truly affect performance, to get us started down this path. For each of those, I tried to give an example of what Situational Performance Optimization could mean for it.
Website Content & Structure
First and foremost, not all websites are the same. Some websites are visually light, while others are extremely complex. Some websites change regularly, while others are fairly static. Some websites have independent pages, while others use a single self-modifying page.
Sample Situational Performance Tip: As is already recommended by PageSpeed Insights, don’t shard hosts that serve less than 10 requests
While Firefox & Chrome ship new versions every 6 weeks, some old browsers don’t disappear that quickly. One common example is IE: While some sites deprecated IE 6 support, most still support IE 7, and the 6-years-old IE 8 still accounts for over 15% of web traffic. Older browsers cripple our ability to use data URIs, CSS media queries and more, resulting in less optimized pages for all clients.
On the other end of the spectrum, some browsers introduce new capabilities we want to tap into. Chrome often leads this charge, with recent examples such as pre-render and WebP image format. By serving the same content to all browsers, we keep ourselves from reaping the benefits of these innovations.
On the mobile front, fragmentation is far worse. We run into many versions of the Android browser (multiplied by carrier & device modifications), differences between embedded and native browsers on iOS, and radically different browsers like Opera Mini. These browsers may use pipelining, have different connection models, provide different cache sizes… Optimizing for one can be very different than optimizing for another.
Sample Situational Performance Tip: Serve different HTML to known, modern browsers, and a more basic, simple page to other browsers. This will allow you to tap into the newest optimization techniques and control the effort split between the different browsers.
One fact that’s likely never going to go away is that some networks are awesome, and others make you want to cry. It makes no sense to treat a new Google Fiber link the same as a poor reception cellular connection or a congested Starbucks WiFi network.
The primary question here is what’s “fast enough”. If the connection is bad, would you consider serving a mobile website to a tablet? If the retina image will add 10 seconds to your page load, would
you settle for a standard one? And would you defer loading your ads when they’ll delay your content by more than 5 seconds?
Sample Situational Performance Tip: When the latency of the connection is bad, reduce image quality (latency can be estimated from the TCP connect, and improved over time). High quality images improve the user experience, but under certain conditions even your designers would agree they cause more pain than value.
Most developers today optimize for a clean cache scenario.
This is the default option – and often the only option – for the vast majority of measurement tools today. This is partly because simulating a “correct” cache state is hard – in fact, my very first blog post was a rant about the flaws of the “Repeat Visit” measurement. And yet, a huge portion of traffic is from return visitors, and their user experience is not what we tune for.
When you do measure your cached performance, there’s little advice around how to optimize it. While browser cache is not scriptable, I believe there’s a lot that can be done if we put our minds to it.
Sample Situational Performance Tip: Make all uncacheable content async, or at least move it to the bottom of the page. This may require some design changes, but it’ll make return visits load much faster.
The last variable I’ll mention is the network protocol. Today, the primary two protocol situations are HTTP and HTTPS. Most best practices today focus on what’s right for HTTP, and overlook the differences in how many roundtrips it takes to establish a connection, security concerns around caching HTTPS content, and certificate validation overhead. I think we should give better advice for optimizing HTTPS.
Looking ahead, though, network protocols would also mean SPDY and HTTP 2.0. Many of the optimization techniques that work well in HTTP 1.1 are anywhere between useless and harmful when these newer protocols are used. We definitely need to guide developers better around how to optimize for the new world situations.
Sample Situational Performance Tip: For HTTPS links, increase the bar for using domain sharding to 30 resources. Establishing an SSL connection requires 3 roundtrips, and each SSL domain usually triggers OCSP requests (which are blocking on some browsers). If you do use domain sharding, try to share the same certificate across all domains.
Sometimes a Cigar is just a Cigar
These are but 5 of many differences between situations, and even they are pretty broad. I’m sure over time we’ll find the top deltas to highlight, but these should keep us busy for a while.
Situational Performance Optimization is more a future than a present. We need to build up our knowledge of which variables matter, understand the best ways to optimize in each case, and provide the tooling to do so. At Akamai we’re starting to do just that with the latest release of Aqua Ion, and by raising awareness to Situational Performance and what it means.
The process that we – as an industry- are going through is a very natural one. You can’t optimize what you can’t measure, and until RUM came along, we weren’t measuring these different situations. Now that we have the insights, it’s time to take our optimizations to the next level.
Guy Podjarny is a Web Performance expert, focusing primarily on Front-End Optimization and Mobile Web Performance. Guy his a frequent speaker at performance and mobile related conferences, and posts his opinions and research on his blog.
Guy is the CTO of the Web Experience Business Unit in Akamai. Prior to that, Guy was the CTO and co-founder of Blaze.io (later acquired by Akamai), and spent a decade working on Web Application Security.