Also, most browsers don't enable HTTP pipelining by default-- they'll reuse a connection if possible, but won't make multiple requests at once for compatibility reasons. Chrome even supported it for a while, but had to remove it because it didn't work (bugs in Chrome, bugs in servers, and the head-of-line blocking problem made it not worth keeping) [1].
[1] https://www.chromium.org/developers/design-documents/network...
Google spread a lot of FUD in their push to get SPDY standardized. For instance they never compared to pipelining, which is relevant because Microsoft found that with pipelining HTTP was essentially just as fast. Google's mobile test where they claimed ~40% speedup used 1 SPDY TCP connection for the entire simulated test run of many sites vs new connections per site for HTTP -- a simple mistake? Maybe, but they didn't take any steps to correct it once they were made aware of it.
"HTTP/1.x has a problem called “head-of-line blocking,” where effectively only one request can be outstanding on a connection at a time."
Does it? Why?
The head-of-line blocking problem actually refers to that behavior-- if I have two requests, one of which is for a 2 MB file and one of which is for a 1 KB file, and I send the 2 MB request first, the server's obligated to completely finish the 2 MB response before it can send the 1 KB file. This isn't great for perceived performance, and runs contrary to how a user expects their web browser to behave (let the small stuff appear first, then let the big stuff finish downloading as it can). HTTP/2 corrects this oversight and allows (through multiplexing) a single connection to behave more like multiple connections would in HTTP/1.1 (multiple transfers can happen simultaneously).
What annoys me somewhat is that HTTP2.0 was basically sold on the back of such demonstrations as 'load 256 identical images'. In that case a proper implementation of HTTP 1.1 with keepalive/pipelining would be just as fast (or even slightly faster due to avoiding multiplexing overhead) as HTTP 2.0.
I think it's pretty pathetic that people can't implement this properly, and I find it worrying that the solution to not being able to implement a protocol properly is to replace it with a more complex protocol.
Which means that if and when we come up with something better, we can deprecate HTTP/2 support, and support only HTTP/next + HTTP/1.1. This helps avoid legacy cruft.
Google did that for SPDY with Chrome - it's no longer supported.
While I'm not convinced that a proper implementation of HTTP 1.1 would actually be just as fast as HTTP 2.0, if you are right, there will be data to show it, and it's not too late for us to change the ecosystem based on that data.
If only the HTTP/2 implementation on the receiving side could tell the underlying TCP stack that it wants to opt out of byte order semantics and to deliver data as it's available. That will decrease latency while not requiring any protocol changes on the sending side.
One thing I have always wondered about these waterfall comparisons is why http 1.1. is slower. Since http 1.1 has keepalive, a browser should be able to send multiple requests upfront to the server, and the server can then stream them back. The lower limit on transfer time should therefore depend only on bandwidth.