Written by Ramón Saquete
Table of contents
When we move our website from HTTP/1.1 to HTTP/2, some Web Performance Optimisation techniques continue to work as usual, while other techniques, which with HTTP/1.1 considerably improved performance, have gone on to offer an insignificant improvement, and some of them can even make performance worse. This is something we need to keep in mind, given the importance of WPO for search engine rankings and user satisfaction.
To understand when these situations can arise, we first need to understand how HTTP/1.1 and HTTP/2 work.
How HTTP/1.1 works
As you all probably know, websites download many different files. When the HTTP/1.1 has to request many files, it can only do it one at a time, meaning that if the browser knows that it needs to request the files: file1.jpg, file2.jpg, file3.jpg, … what the browser does is first request file1.jpg, and until the request reaches the server and the server returns the entire file, the browser cannot request file2.jpg. Again, until it doesn’t receive file2.jpg, it cannot request file3.jpg, and so on. As a result, the browser spends quite a lot of time blocked, unable to do anything, while the requests and responses travel over the network.
To try and minimise the time the browser spends not doing anything with the HTTP/1.1 it paralyses the download by opening various connections, in a way that the browser with two open connections can request file2.jpg and file3.jpg at the same time, one for each connection, but it won’t be able to request any other file until one of these two files finishes downloading, so it continues to be stuck for some amount of time. Moreover, this solution results in these two open connections having to fight for the available transmission speed, not taking full advantage of it, and it gets progressively worse the more open connections there are. For that reason, browsers limit the number of simultaneous connections to a low number, usually 5 or 6. In the following image we can see an example with 3 simultaneous connections:
How HTTP/2 works
The HTTP/2 allows the browser to request all the files the website needs, at the same time and using just one single connection, returning them all at the same time as well. Its network flow diagram would look like this:
To do this, it applies serial multiplexing, which is a common technique in data transmission. It consists in dividing the files into chunks, and send a chunk of each, in the following way and order: first chunk of file1.jpg, first chunk of file2.jpg, first chunk of file3.jpg, …, second chunk of file1.jpg, second chunk of file2.jpg, second chunk of file3.jpg, …, and so on.
As a result, and due to the way the protocol works, the browser doesn’t spend stuck all that time, and the transmission speed is taken much better advantage of.
Moreover, the browser can assign priorities to the transmission of files, on those which are needed to paint the website immediately, which means the server will send the chunks of the most important files first. With HTTP/1.1 something similar happened, because files were ordered by priority in the browser’s request queue, but this did not ensure they would reach the server in the same order. With HTTP/2, files do not have to wait in a queue, instead they are directly sent, and download priorities are handled much better, because the server knows which ones it needs to return first.
HTTP/2 introduces other optimisation improvements, such as compressed headers, binary format, and removal of redundant information, all of which reduce the amount of information to be transferred, but neither of them is as effective as multiplexing. The only changes we need to keep in mind to know which optimisation techniques become obsolete with this new protocol are multiplexing and the fact that HTTP/2 keeps the TCP connection active.🤓 Multiplexed and serial file transmission is key to understanding which WPO techniques become obsolete with the use of HTTP/2.Click To Tweet
When can we use HTTP/2?
Both the client and the server need to enable HTTP/2, to be able to use this protocol. Presently, all browsers allow HTTP/2, but this is not the case with the crawlers used by search engines to crawl websites, including Googlebot. This means the website will be indexed and downloaded with HTTP/1.1. Another mandatory requirement is to use the TLS protocol under HTTP/2 to offer HTTPS. This is a restriction imposed by all browsers to promote use of HTTPS, as they do not allow use of HTTP/2 without secure communication, while specs and server do.
Moreover, the server needs to allow the use of a TLS protocol extension called ALPN (Application-Layer Protocol Negotiation), which is used to negotiate with the server whether the communication is going to be made with HTTP/2 or HTTP/1.1. As an alternative to this extension, the NPN (Next Protocol Negotiation) was used, with the same purpose, but on 31/05/2016 Google updated its browser to only allow ALPN, which forces the server to have an updated version of the operating system to use this and be able to enjoy HTTP/2. Google enforced this because ALPN is much faster, as it prevents an additional roundtrip whereas NPN does not.To be able to enjoy HTTP/2 both the client and the server need to enable it, and work with HTTPS and ALPN 👍🏽Click To Tweet
Despite all these requirements, HTTP/2 has already replaced HTTP/1.1 on more than 25% of websites, and its growth is of approximately 10% per year. There are also rumours that Googlebot could start using it any time.
WPO techniques that become obsolete with the use of HTTP/2
The server response header “Connection: Keep-Alive” makes the HTTP/1.1 to keep the TCP connection open after downloading a file, so that the TCP doesn’t need to open and close the connection with each downloaded file. This is important, because TCP creates a roundtrip for opening the connection, and another roundtrip for closing the connection, in addition to the roundtrip needed to transfer the file with HTTP (roundtrips should be avoided because the data transfer over the network is one of the tasks, which takes the longest when a website is loading). This is how it works:
- First roundtrip:
- The TCP sends a request from the client to the server to open the connection.
- The server returns a response with the acceptance and an identifier of the connection.
- Second roundtrip:
- The HTTP requests a file from the client.
- The server returns the requested file.
- Third roundtrip:
- The TCP requests to close the connection from the client.
- The server accepts to close the connection.
If it needs to download another file, it repeats all the steps, but if it leaves the connection open, it will only need to request the new file.
HTTP/2 always leaves the connection open and ignores the “Connection: Keep-Alive” header. This means that, if our website uses HTTP/2, it will only make our headers weigh more.
Reduce the number of requests
There are various WPO techniques allowing to reduce the number of requested files. As I’ve already said, when requesting several files with HTTP/1.1, the browser gets blocked. With HTTP/2, this no longer happens, rendering these techniques obsolete. But let’s better analyse what happens with each of them:
This technique consists in unifying various images into one, then cropping them using CSS and placing them where they’re supposed to go on the page. This technique is no longer effective, and the only thing we can do –if we’re lucky– is if we unify visually similar images, the unified file may end up weighing a little less than the images on their own. In any case, this is a tiny improvement, so the CSS sprites technique is no longer worth using for optimisation. If we want to do it for code organisation purposes, though, it’s a whole other story. If used, try not to unify images that are not going to be used, as it will unnecessarily increase the file size. I, personally, do not recommend it, because when we implement changes, we could forget the images we no longer use in the sprites.
Inlining images with DATA URIs and CSS code in the HTML
Inlining images with DATA URIs consists in placing images in text strings inside the CSS file, or directly in the HTML, instead of linking them. Including the CSS inside the HTML with the <style> tag prevents us from linking it in a separate file. These techniques can be applied for two purposes: to decrease the number of requests, and/or to deliver critical resources immediately. The first reason is made obsolete with HTTP/2, but the second one regarding critical resources continues to be valid. Critical resources are files, which are going to be used for painting important parts of the page (mainly those located in the above the fold, or without scrolling).
Inlining an image prevents the browser from having to request a file that used to be linked from it, thus avoiding a roundtrip. For example, let’s imagine we have an HTML file, which links a CSS file, which in turn links an image. Regardless of the protocol, this generates 3 roundtrips, because each file will inevitably be requested one after the other, because we need to have the previous one to know which one is the next. But if we inline the image in the CSS, when we download it, we’ll already have the image, meaning we’re saving ourselves an additional roundtrip. Or, we could inline the CSS in the HTML with the <style> tag and with the image, and we wouldn’t have to download additional files once he HTML has been downloaded, preventing two additional roundtrips. The problem with this technique is that the images and the CSS inlined directly in the HTML are not stored in the browser’s cache, so it’s not recommended for websites with many recurring visitors. So, in summary, these techniques, when used correctly, still make sense.
There is a new technique for delivering critical resources, so that they’re downloaded with the HTML, which allows the browser to store the files in the cache. It is called HTTP/2 Server Push, a subject I’ll tackle in some other post.
Parallelise the number of simultaneous requests
As we’ve already seen in browsers using HTTP/1.1, they parallelise requests by opening several connections, which, depending on the browser, are limited to 5 or 6, and requests are launched for each of them. This limit is set by the browser for the domain, so we can increase the number of requests it launches if we use various domains. There are two techniques which do this:
This technique produces some improvements for HTTP/1.1, if we’re careful not to overdo it with the subdomains and making tests. With HTTP/2 not only we’re not going to get an improvement, it’s actually going to worsen our performance. This is primarily due to the fact that this technique needs additional time to resolve each of the subdomains to their corresponding IPs. With HTTP/1.1 this loss could be compensated with the reduction in time the browser spent stuck, but with HTTP/2 we don’t have this problem, and we waste time on the DNS resolution of additional domains, and making more unnecessary connections. Therefore, if we use HTTP/2 and this technique, it is best we get rid of it.
CDN (Content Delivery Network)
A Content Delivery Network consists in a worldwide reverse cache proxy network (servers which cache the content of a main server) connected directly to the core routers with the same IP. The core routers are Internet’s core routers, and with these proxies connected directly to them we get a faster access to any server, because to reach a server we always have to go through a router hierarchy, which go from the core router to routers, which get increasingly smaller, all the way down to the router connected to the server network. Moreover, core routers are configured to balance the requests to the cache proxy of the closest or fastest CDN.
If we have no other choice but to use the CDN to cache only static resources, either because the CDN provider doesn’t offer other service, or because we want to keep the information updated by the minute, we should use only one CDN subdomain.
In any case, we must ensure that our CDN provider supports HTTP/2, so that the improvement the CDN can offer is worth it.
HTTP/2 on its own is a considerable improvement for a website’s performance, but to make the most of it we must avoid using domain sharding and CDNs under HTTP/1.1.
Unifying CSS files and using CSS sprites, while obsolete and no longer worth our time, are not going to affect us negatively if they’ve already been implemented, so we can leave them be. Moreover, Googlebot’s crawlers still use HTTP/1.1, so if we continue to use these techniques for file unification, the performance will improve for them.