HTTP/1's Cure is HTTP/2's Poison, the front-end performance techniques developed for HTTP/1 can hinder performance over HTTP/2.
HTTP/2 is the next version of HTTP (Hypertext Transport Protocol). HTTP is the protocol that forms the foundation of the world wide web, handling the initiation of the request from your browser and the response from the web server.
HTTP/1 Performance Best Practices
In the relentless pursuit of performance over HTTP/1.1, the current version of HTTP, we've adopted various best practices:
- Concatenation - Combining multiple CSS or JS files into one single CSS or JS file Why? To reduce the number of HTTP requests. With HTTP/1 requests are expensive as setting up the connection to the server is slow.
- Cookie-less Domains for Static Resources (images, CSS and JS) Why? Cookies add extra bytes to HTTP requests so as cookies often serve no purpose in requests for static resources such as images we move them to a separate domain so that any cookies set on the website are not passed with requests for static resources.
- Sprite Images - Combining several images into one large image and then using CSS to only displaying a portion of that image Why? As above, to reduce the number of HTTP requests, which are costly in HTTP/1.
- Sharding - We split components across multiple domains or sub-domains Why? To maximise parallel downloads and avoid a legacy limitation of some browsers where they could only download 2-6 resources simultaneously from a single domain. By splitting components such as CSS, JS and images across domains or sub-domains we avoid that limitation.
Whilst these best practices (some may say "hacks") improved performance over HTTP/1 they actually have the reverse effect over HTTP/2. Just to be clear, switching a HTTP/1 optimised website to HTTP/2 will improve performance, but the above optimisations will actually hinder thepotential performance over HTTP/2.
What's new in HTTP/2?
Header compression reduces overhead and therefore increases performance. HTTP/2 also lessens the number of headers that have to be sent after the initial request by retaining some context so un-changed header values do not need to be re-sent.
This compression means including cookies in requests is not so much of a problem compared to HTTP/1 and actually the extra DNS look-ups required when serving static resources on different domains or sub-domains (exacerbated further when SSL is involved) makes the approach more costly in HTTP/2.
In contrast to HTTP/1 which is ordered and blocking, where only one request can be outstanding on a connection at a time. In HTTP/2 multiple request and response messages can exist at the same time on a single connection. Therefore splitting components across multiple domains or sub-domains to achieve parallel downloads is no longer necessary as multiplexing allows HTTP/2 to perform parallel downloads over a single connection.
Server "Push" Responses
This allows servers to "push" responses proactively to clients. If you've ever inlined CSS into a HTML document's HEAD you are almost simulating server push. As the CSS is being sent to the client when they requested only the HTML.
How should we change our approach to prepare for HTTP/2?
As requests are no longer as costly, it makes greater sense to only load in CSS and JS when it's needed rather than throwing perhaps more data than we need to into a single request.
Also when a single character is modified in a concatenated file it invalidates the cache for the entire file, forcing clients to download what could be quite a large file. So multiple smaller files enables more granular cache invalidation and allows the browser to start processing the data quicker, rather than having to wait for a larger file to download fully.
The benefit of loading multiple images into sprites is decreased, but still present if you have several images that could be included in one image. As with concatenation, carefully consider whether one large sprite image is better than several small images if they are not likely to all be needed from the get go.
Reconsider resource inlining
Rather than including above the fold CSS in the HTML document HEAD, it should remain in an external file where it can be cached and it does not inflate the size of the document in which is it contained.
Thanks to multiplexing we can instead use a single domain for our static assets, reducing the number of DNS look-ups needed.
Reconsider cookie-less domains
Thanks to compression cookies are less costly in HTTP/2 and the extra DNS look-up (and SSL negotiation) may be more so.
Browser support is very good, the latest versions of all the major desktop browsers already support HTTP/2 (HTTP/2 is only supported in Internet Explorer 11 on Windows 8). Support has been present in Chrome and Firefox for several years and arrived in Safari in the latter part of 2014.
Any non-compatible browsers would simply fallback to using HTTP/1 so there's little in terms of barriers to using HTTP/2. We’re looking forward to Nginx’s implementation of HTTP/2 due later this year.
HTTP/2 is largely based on the SPDY protocol developed by Google, which whilst non-standard is already in use today but is not likely to be supported for long after HTTP/2 takes hold.