A List Apart

Menu

Using HTTP/2 Responsibly: Adapting for Users

A note from the editors: This article is part one of a two-part series exploring the new HTTP/2 protocol and using it responsibly. Be sure to read part two, Considering How We Use HTTP/2.

With HTTP/2 ticking up steadily in use, it’s clear that there’s something to this long overdue update to the protocol. Implementing it, however, not only changes how websites are delivered to the user, it demands that we think critically about how we migrate existing sites to the protocol. More importantly, it demands that we consider our users’ capabilities.

Article Continues Below

Whether you’ve already migrated your site to HTTP/2 or you’re bracing yourself to take the plunge, there are challenges when it comes to tuning your site’s front end architecture to be the most performant it can possibly be for all your users. Perhaps you’ve read about what it takes to get your site ready for HTTP/2. Perhaps you haven’t. If the latter describes you best, it’s not worth getting into the weeds here. The gist of it is that HTTP/2 optimization patterns are the opposite of those for HTTP/1. Your site will perform better on HTTP/2 if you avoid practices that combine files, because caching for those resources will be more efficient when they change.

In order to cope with the limitations of the aging HTTP/1 protocol, we were more than willing to sacrifice some degree of caching effectiveness for return visitors in order to speed up the initial loading of a site. Thus, techniques like scripts and CSS concatenation, image sprites, and inline assets were embraced. In a world that’s creeping toward HTTP/2, however, we’re told to abandon these practices —and for the most part, rightly so.

The reality of the situation can be more complex than we initially thought. While HTTP/2 support on both the server and client side is steadily increasing, browsers that can’t understand the new protocol will linger on for some time yet—and that doesn’t just mean Internet Explorer. It also includes browsers like Safari on older versions of OS X, UC Browser, older versions of Android Browser, and Opera Mini.

Sometimes we hurt the ones we love

HTTP/2 support is not a one-sided affair. In order for it to work, the server must not only implement it, but the browser must also be capable of understanding the new protocol. When a browser that understands HTTP/2 begins requesting content from an HTTP/2 server, the exchange will predictably occur in, well, HTTP/2. In the case of an older browser like Internet Explorer on Windows 7 (or even a current browser such as Opera Mini), the conversation proceeds in HTTP/1. The underlying mechanism that drives this behavior is nuanced, but it can be considered progressive enhancement in that we’re not breaking the experience for users on platforms that can’t use HTTP/2. They’re merely getting a less optimal experience.

Whether you’ve made the jump and optimized your site for HTTP/2 already, considering the jump from HTTP/1, or somewhere in between, it can pay (sometimes quite literally) to understand how these optimizations can impact your site’s users. Depending on your audience’s capabilities, a site optimized for HTTP/2 may well be detrimental for a segment of your audience.

HTTP/2 enjoys broad support among users in the global sense. According to the popular feature support index site caniuse.com, HTTP/2 currently enjoys support of roughly 78% of all browsers currently in use. Some fringe browsers such as IE 11 below Windows 10, and Safari on OS X below El Capitan muddle the picture a bit. You can count on at least 72% of users globally to support HTTP/2 (at least at the time of this writing).

Of course, this is just the big picture, and it isn’t an indicator of what your specific audience looks like. You need to consider the source of your visitors and what browsers they tend to use. You also need to consider where your users reside in the world.

In the rudimentary statistics I’ve compiled from caniuse.com, I’ve found that users in developing nations tend to use browsers that don’t support HTTP/2 more often than those in developed nations. Following that up with statistics from Akamai’s Q3 State of the Internet Report, developing nations generally have a lower quality of internet infrastructure than developed nations. I won’t get into the data here (though you can have a look for yourself), but if you’re curious, you can check out this short write-up I’ve done on the subject to get some context.

The confluence of these two truths creates a challenge in how we optimize sites for our visitors.

  • Even if you set up a web server that uses HTTP/2, there’s a segment of your audience that won’t receive the benefits because their connection to your server will be over HTTP/1.
  • Even worse, if you’ve optimized your site for the best performance on HTTP/2, you’ve likely made your website slower for users with older browsers.

“Aw, hell! They should just upgrade their browser!” While some of us have said this at one time or another out of utter frustration in the face of solving a challenging problem, this is a terrible sentiment. It presupposes that the user has the ability to upgrade their browser, but they’re just too damn lazy to get around to it.

The more likely problem is that users in developing nations are reliant on antiquated infrastructure or bound to a restricted data plan that makes this impractical. We need to be empathetic to this reality. It behooves you to know how many of your users are running HTTP2-capable browsers, and how many aren’t. All you need to determine this is a Google Analytics account and caniuse.

caniuse is able to comb through your site’s visitor data, then give you the status of support for a particular browser feature in the context of your site’s visitors, rather than for a particular country. Perfect for determining browser support for HTTP/2 in your audience! By opening the settings panel in the site and then clicking the “Import” button under the “From Google Analytics” header, you’ll be prompted to allow caniuse to access your analytics.

Here’s a real world scenario in which I’ve used this tool to determine an audience’s HTTP/2 support: My friend runs a reasonably popular blog about guitars and guitar accessories that receives roughly 30,000 pageviews per month. When I fed the site’s Google Analytics data into caniuse, it showed that the site’s audience over the most recent 30 day period had about 91% support for HTTP/2 (Fig 1).

Visual comparison of two equations: All Web Site Data (78.47% + 12.27% = 90.74%) and Global (70.13% + 5.95% = 76.08%)
Fig. 1: caniuse.com’s support threshold for HTTP/2 for a specific site, labeled “All Web Site Data.”

91% seems like a high level of support for HTTP/2 —and it is! Despite that fact, you must take into consideration the raw number of pageviews from browsers fetching resources over HTTP/1 because they don’t support HTTP/2.

Some basic math reveals that this segment represents 2,700 pageviews per month. Furthermore, the quoted support of 91% includes browsers that partially support HTTP/2. In this specific example, we can only be absolutely certain that around 78% of this site’s visitors support HTTP/2. This means that anywhere from 2,700 to 6,600 pageviews may be served over HTTP/1. The actual number is somewhere in between, and even though this is a minority of users, it’s still a significant number of pageviews on its own, and it may be too large for you to simply ignore.

Adapting your users’ limitations

By this point, we know three things:

  1. HTTP/2 servers will downgrade to HTTP/1 when responding to HTTP/2-incompatible browsers.
  2. HTTP/2-specific front-end architecture optimizations are usually detrimental to users on browsers that are HTTP/2-incompatible.
  3. Users in developing nations tend to have a lower level of support for newer browser features like HTTP/2, and tend to have slower internet connection speeds.

The only thing we don’t know at this point is how to fine-tune our content delivery so that it’s beneficial for everyone. Before we can really think about modifying how content is delivered to the user, there are a couple of things we should consider first.

Is HTTP/2 right for you?

Assuming you haven’t already migrated to HTTP/2, there are a few things to take into account before you invest time and resources into making the switch:

  1. While the HTTP/2 specification doesn’t explicitly require SSL, it is a de facto standard in that browsers require it. If you implement HTTP/2 on your server and fail to install a valid SSL certificate, the connection will always downgrade to HTTP/1. For the budget-conscious, certificates range from reasonably priced to 100% free via Let’s Encrypt. Even with free certificates, implementing SSL still represents a cost to your organization. It takes time and effort in the form of QA testing to ensure that existing sites aren’t broken in the migration.
  2. If your site’s footprint is very small, HTTP requests are few, and upgrading to SSL isn’t pragmatic, you may already be well-served by HTTP/1. This is especially true if you’ve implemented HTTP/1-specific optimizations and it would cost significant developer time to unravel them into HTTP/2 optimizations. This doesn’t mean that you shouldn’t upgrade to SSL, though.
  3. If most of your site’s audience uses browsers that can only support HTTP/1 and your site is well-optimized for it, you’re probably already well-served by HTTP/1. But again: consider SSL anyway.

Let me be totally clear: HTTP/2 is an excellent performance enhancement for large, complex sites with lots of assets that would otherwise perform poorly on HTTP/1. We just need to talk about how you might be able to mitigate some of the pain for users with less capable browsers, and that begins with identifying those users when they visit.

Checking for HTTP/2 and adapting to users’ needs

How you deliver content based on a given user’s HTTP protocol version depends on what technologies you have available on your host. You’ll usually use a back end language like PHP to modify the markup you send to the client. Regardless of the technology you use, there are two conditions you’re covering:

  1. If the user is on HTTP/2: You’ll serve more and smaller assets. You’ll avoid stuff like image sprites, inlined CSS and scripts, and concatenated style sheets and scripts.
  2. If the user is on HTTP/1: You’ll do the opposite. You’ll bundle files, use image sprites, and inline small assets.

The specific mechanism by which you detect HTTP/2 support will depend on the back end language you use. In PHP, we can determine the protocol version of a given connection by checking the $_SERVER["SERVER_PROTOCOL"] environment variable. Below is a one-liner that stores the HTTP/2 connection status in a variable named $isHttp2:

$isHttp2 = stristr($_SERVER["SERVER_PROTOCOL"], "HTTP/2") ? true : false;

Using the stristr function, the $_SERVER["SERVER_PROTOCOL"] environment variable is checked for the presence of the substring "HTTP/2". If the substring exists, $isHttp2 is set to true. If not, it’s set to false. From here, it’s up to you to apply this logic to your site, but let’s look at a couple of things you could do. For instance, you could add a class of http1 to the

tag:

<?php
if ($isHttp2 === false) {
	?><html class="http1"><?php
} else {
	?><html><?php
}
?>

Using this class, you can adapt your CSS to serve an image sprite for HTTP/1 users, and individual images for your HTTP/2 users. Or maybe serve a separate CSS file with inlined assets using the data URI scheme. Speaking of serving different files, you could change your markup based on the user’s protocol version to change how you serve assets to the client:

<?php
if ($isHttp2 === true) {
	<script src="/js/script-1.js"></script>
	<script src="/js/script-2.js"></script>
	<script src="/js/script-3.js"></script>
} else {
	<script src="/js/script-bundle.js"></script>
	<?php
}
?>

Or you could change your markup to inline some critical CSS for HTTP/1 users with the handy file_get_contents function:

<?php
if ($isHttp2 === true) {
	<link rel="stylesheet" href="css/critical.css">
} else {
	<style><?php echo(file_get_contents("css/critical.css")); ?></style>
	<?php
}
?>

Of course, on HTTP/2 sites, you would take any content that you’d normally inline and use server push to confer the benefits of inlining without actually inlining content. How you specifically adapt your site’s content delivery based on the visitor’s protocol version really depends on your specific situation.

This concludes the first article! In part two of this series, we’ll:

  • Apply these techniques to a real world scenario
  • Use a performance testing tool to check for meaningful comparisons se a build system to generate HTTP/1-friendly assets so you can keep your workflow clean and efficient.

Further reading

Learn more about boosting site performance with Jeremy’s book Web Performance in Action. Get 39% off with code ALAWPA.

3 Reader Comments

Load Comments