 So my name is Surma, and I work with the Google Chrome team in London. And I'm here today to get you guys excited about HTTP2. So I know that this is a long day, and there has been great content being thrown at you by good-looking people. And so I thought I'd start with a TLDR, which is Switch. There really is no way for you that this could perform worse than your current HTTP setup, your current HTTPS setup. So what I'm saying is, basically, HTTP2 is performance for free. So you just go ahead, enable it, and if you actually can justify it and put a little more effort into it, HTTP2 offers even more levers for you to put even more optimization in there and get more performance out of your site. From now on, by the way, I'm going to call HTTP2 H2, because that is A, the official symbol for the protocol. So even Chrome Inspector signifies HTTP2 that way, and it's so much easier to say. So I hope you can accept that. As you've learned in the last two days, and especially today, performance matters. And as I said, there's a lot of features that are on top of H2 that give you more possibilities to optimize your website. And I'm using the generic term performance here, because it can really be applied to a lot of different things that you have. It could be the time to first render. It could be the total load time of your page. All of these are more optimizable once you actually have H2 enabled. So hopefully with this, I got you interested enough to actually listen to me. And I want to start with a little history on how we ended up where we are today. So H1 is old, HTTP1, that is. Tim Berners-Lee specced the first version, which is HTTP 0.9 in 1991. Just think about that. That is over 20 years ago. And this is what I originally had in mind. It is a simple document. You have text. You have a little bit of formatting going on. And you have links to other websites. And that is really what the H in HTTP stands for. It's hypertext. You have a web of documents. And this is allegedly one of the first, if not the first, website out there. And this is what the protocol was designed for. About five years later, HTTP 0.1 came to be. And it added basically a few headers, a level of meta information, and a security protocol. So in HTTP 0.9, you had to get, post, and had. And in HTTP 0.1.0, put, delete, and our favorites, link, and unlink came to, which we all use daily, right? So these are more methods that added not all of them, but obligatory, as you can tell. And that is basically what we start with until then. And then only a year later, HTTP 1.1 came. Which is kind of weird to move that fast suddenly, but there were problems that had to be addressed. So HTTP 1.1 basically added the options method, which you needed to do like cross origin communication. You had the host header, which was now obligatory because people started hosting the multiple websites on the same server. And you had more control over caching. But most interestingly, Keep Alive was added. And I say that is the most interesting part, because websites now started to look like this. This is not really a document anymore, nor is it just hypertext. This is really just more like hypermedia. You have things, images, videos, sounds that refer to other things on the web as well. And if you look at the last four years alone, the total transfer size of a website has tripled in the last four years. And as I said, HTTP is over 20 years old. And obviously, since we are kind of starting to abuse HTTP 1.1 here, performance went down. It's really mediocre at that point. So people started saying that H1 had flaws, which is not really right. We were just abusing it for things it wasn't designed for. And so we came up with workarounds. Workarounds to address these problems and kind of kept it going up until this day. And these best practices, which are really workarounds, which are really hacks, were things like concatenation, sharding, spriting, cashing, and vulcanizing, and all these kind of things that, for some reason, we have to do to not have an abyssal performance nowadays. And all of these hacks address problems, as I said. And the most notorious of these problems is head-of-line blocking. Head-of-line blocking is the phenomenon that when you send a request on a connection to a server, that that connection is from now on useless until that point when the server has responded completely with a response. And originally, a browser was only allowed to have two concurrent connections to the same server. So we had two connections, on each of which we put out a request. And you had to wait until one of these was finished until you could reuse the connection. So obviously, there's kind of a bottleneck there. And we realized that. And people started, OK, let's raise the limit. Let's go to six connections. And you can kind of realize six connections is not really enough again. And it just postpones the problem a little bit. The GoLang guys are actually a lot of people, but the GoLang guys wrote a great demo showing off this problem where they tiled an image into 180 smaller tiles, included all of these tiles in a website with image tags, and just served it over HTTP1. And as you can maybe hopefully tell by this graph, first of all, you see the six connections and the seventh one to load JavaScript from another server. But you see the six connections. And there's a lot of sparseness there. The connection is not really saturated at this point. So I also looked at the saturation graph. So we look at the green lines of both of these graphs. And you can see that with age one, there is almost no saturation whatsoever. And with age two, it's at least a lot better. Still not optimal, but a lot better. The second big flaw that we had, or that there is in HTTP1, is that headers repeat a lot across requests. The most notorious examples of headers that do repeat are user agent and cookies. Both of them are long and static, and they just keep being added to each and every request. That comes from the fact that HTTP used to be status or is supposed to be stateless, each request being completely independent from the next. So people needed to work around that and started using sessions and identified a session with a cookie, with a long UUID in the cookie. And each of these cookies would be appended to every request being sent over and over, which really is just a waste of bandwidth. Another minor part is that people started like, OK, I can compress my data. Obviously, I can just Gzip everything that goes over the wire. But that would only apply to the actual data. The headers, which are still highly compressible, would still not be Gzip. And that's also just a missed opportunity. So at that point, people realized that we were not using HTTP-1 for what was designed for and something else had to come up. So we started doing speedy. And we tried out a few things and kept the stuff that was working. And on the basis of speedy, HTTP-2 was specified. And this is where the interesting part of this talk actually begins, because now we are at the glorious era of HTTP-2. So the first scary things I want to address is H2 has the same semantics as H1. So you still have request response. You still have headers, which are key value pairs. You still have a body, which can be any kind of content. So your apps will all be able to stay the same as they are right now. You don't have to touch the code at all. The only thing that's different is how these requests are going to be encoded on the wire. They're wrapped differently on a binary level. The second scary part is that H2 is a protocol upgrade. So people might be thinking, how can I upgrade? Am I going to lose clients? No, you don't, because every connection starts out as H1. And then it's an upgrade to H2. And if this client doesn't support H2, it will just stay on H1 and everything work as before. But what is H2, really? First of all, it's a single TLS encrypted connection. Technically, in the spec, there is a protocol called H2C, which is the clear text version of H2. But most browsers have actually opted out of implementing that. So there's really no way for you to get around the TLS part of this. But we had a talk of Emily yesterday, I think. And we have services like Cloudflare and Less Encrypt, which is going to go and open beta on December 8. So it should be really easy for you to set up TLS at this point. And yes, I said it's a single connection, because head of line blocking, the issue of having only six connection is being addressed on a protocol level. So we can actually work with a single connection. The stream, the connection itself, actually looks like this. What used to be a request response pair in HTTP1 is now a logical stream. That's what it's called. And all streams actually share this connection. They're multiplexed on the single connection and share the bandwidth of the single connection. And head of line blocking is not a thing anymore, because these streams are being chopped into frames and put onto the connection. And that means that if one stream goes into the blocking state where it's waiting for a response or for the client to push more data to put on the wire, another stream can take over and utilize the connection fully. So you can see how this will actually solve the head of line blocking thing. Actually, something, an additional feature is that the client can specify dependencies and weights for each of these streams so that it can say stuff like, this stream is only useful if the other stream has already completed and that the weights are there to distribute the bandwidth more appropriately for the application that you are doing. However, this feature is on the client side only right now. It's not been exposed to the server side just yet, but it is being considered. So as I said, it's split into frames or chopped into frames. And there's multiple frame times, but the most important ones are header frames and data frames. So as I said before, we had headers as key value pairs of strings. And we had data, which could be whatever you need. So it kind of makes sense to split these apart because they have different content types, right? So this is what's actually been happening, so that the stream now actually looks like this. And you have frames of data and header data being on the wire. And remember that all of this is end-to-end encrypted because TLS is enabled. And there's a lot of things new in H2. And I'm going to address most of them, but this feature alone, having no head of line blocking and a single connection that does multiplexing, actually invalidates a lot of the best practice that we already know and had to do. All of these best practices here, like concatenation, inlining, vulcanizing, and spriting, were there to reduce the number of requests and to get more out of a single request. It had also a very bad side effect that it made caching really inefficient because if you think about, you would have a lot of icons on our website and you would sprite them into a big image, changing a single item, a single icon, would invalidate the entire sprite image and you would have to redownload it all over again. And now, requests are cheap and you can just leave the tiny images on the server and have them cached individually. So here's a demo of the tiled image that I showed earlier. And one of the videos is H2, and one of the videos is H1, and it's your guess which is which. And just keep in mind, there is no feature being used here except the fact that head of line blocking is gone. It is all that's happening here is a static website being delivered over H2 with 30 milliseconds emulated latency and a 3G emulated network bandwidth, so to speak. And yes, cache is being busted. So you can see the impact of this feature alone is already huge. To visualize this a little bit more, these are the waterfall graphs. And you can see that H2 is much, much steeper, which is because on the left side, we have the limit of six connections on the right side we don't. So you can see that we always have this chunk of sixes with indentation on the right side we don't really. So H2 is much like is to saturate the connection, the available bandwidth that you have. So the question really is, how does this feature of having a single connection with the head of line blocking, how does this translate into real life? And luckily, Financial Times did an actual life test where they moved their static assets to an H2-enabled CDN of Akamai. And they kind of segmented their clients into three groups. The groups are the clients that didn't support H2, the clients that did support H2 but didn't use it, and the clients that did support H2 and did use it. And as you can tell by the graph that this alone, just moving the static assets to an CDN with H2, has a great impact for the amount of time it takes to get to the mobile load event. To get back to the split frame types of header data and of header frames and data frames, this is a great opportunity because now, since they're separate from the data, we can actually compress headers now. And not only that, they actually came up with a compression specific for HTTP headers. And since it's glorious and new, it gets stars. HPEG, which is the compression for headers, is defines the notion of the compressor and decompressor, which is pretty normal for a compression. But the interesting thing is that these compressor and decompressors work on the connection rather than on each of the streams. So you have one instance and all the requests go through the same instance, which gives us the ability to actually back reference header values that have been used in previous requests while compressing the current request. So I wanna go into this a little bit more. So we send out a request to example.org and wanna get the index HTML and the compression works just like GZIP is a Huffman encoding kind of and additionally it has a lookup table. So it just has the first 62 entries of that lookup table have been extracted from the most popular websites that are out there and the requests that they get, obviously. And also pseudo headers have been added to accommodate the things like the method and the path, which are technically speaking, not headers, but should also be compressed. And what happens is that the compressor goes through the lookup table and tries to find the values that are in the request. So as you can see, the method get is in the table. The slash index HTML path is in the table. The header key host is in the table and only the value is not. And so what happens is that it's actually being encoded as a single, as a few bytes in the say indexes in the table and then just a Huffman, a GZIP of the string example.org. The interesting thing now is that after this has been completely transferred over the server, the values that weren't in the table are being added to the dynamic part of the table, which starts at index 62. So now we actually have host example.org in the table. That means once we set out the next request, and this time we wanna post to slash something, we can reuse the table and don't have to re-encode example.org. However, in this case, slash something, isn't it, that's going to be GZIP and going to be able to be tabled afterwards just as well. And the nice thing about this is this works completely transparently. There's nothing you need to do. Once you enable H2, this just happens. You will reap the benefits of having less data over the wire just by switching. You don't need to change your app. You don't need to have some kind of configuration magic going on. And that is really something you should keep in mind. And again, just by having one single new feature, a lot of best practices that we have actually become invalid or actually counterproductive. So as I said, you have this notion of a shared compressor and a decompressor. So having multiple connections is actually bad for you. So you still wanna do CDNs, obviously, because you wanna be geographically close to your clients, but you wanna keep the number of origins as low as possible to exploit the fact of the shared compressor as much as possible. So the same thing goes for sharding. It's the same notion you don't wanna do multiple connections. And also, non-changing cookies are actually highly compressible now. So what used to be kind of an anti-pattern of encoding session data into cookies could actually become viable now because it's so highly compressible. Up until this point, everything works the same. That's what I mean. You can just switch and reap all the benefits that I was talking about. There's nothing you need to do. But as I also said, there is features which you can exploit when you change your app a little bit and it gives you more room to improve your website in terms of performance. The probably the best-known feature of HTTP2 is push. And it is not to be confused with a web push notification API. Push is a technology or something of the protocol that allows you to respond to a request that hasn't even been sent yet. And what that means is that if I request index HTML off of a server, the server could be like, okay, here's your index HTML. He's obviously gonna answer. But then the server can go and be, okay, you got index HTML, but I'm pretty sure you're also gonna need style CSS and script.js. So here goes well with those. And those are called push promise frames. And once the client has done parsing, the index HTML actually is aware of the fact that he needs style CSS and script.js. It's already in its cache and the request will never go out to the network. And Eric Bidelman took a Polymer app, removed concatenation and vulcanization and then added push to it where he pushed all the resources that he needed. And saw a 60% improvement in load time for the app. So a client is also able to cancel a push if the client is sure it doesn't need it, but still be careful in what you push because pushing mindlessly can also have a negative impact. So it's something where best practices still really have to arrive on what is good to push or what is not good to push. So as you can tell, H2 does a lot for you. But there's still things that you as a developer need to take care of. So like setting sensible cache control headers, reducing the number of origins and therefore DNS lookups, taking care of a good first render which we have had talks about. And most importantly actually compression. Compression just like H2 is performance for free. Just have Gzip enabled on your server. You don't need to upload Gzip files as something your web server does for you. Compression on the fly because at this point, almost half of HTML, a third of CSS and a quarter of JavaScript are still being sent uncompressed over the wire which is just a wasted opportunity. And as you can see, I'm emulating a 56 kilobit connection here admittedly but the performance impact is huge just by enabling Gzip. Actually compression used to be enforced by speedy but they removed that because it doesn't make sense on every type of content. JPEGs and movies, for example, are already highly compressed. So it's just wasted CPU cycles to compress those with Gzip all over again. So it is your responsibility to do that, to enable Gzip. So I guess at this point, the question, the most interesting question really is, should you do it now? When can you start? How do you get H2 onto your development machine or into your production environment? Ironically, at this time, the browsers are actually a hat of the service for once. All the major browsers support H2 and can I use as their full support? That is technically not true because stream weights and stream dependencies are not well supported, at least not consistently but HPEG and the multiplexing protocol itself is supported across the board and you can be sure to use and then there's still the upgrade feature that if for some reason the browser doesn't support it, it's just gonna stay on H1. On the server side, at least very recently, a lot of the famous servers have merged or started working on an H2 implementation. Google Cloud Platform is actually pretty interesting because the second you enable TLS on your project, everything will work over H2 and some of these servers and Gzip is one of them actually allow you to specify pushes by setting a link header in your response. In terms of languages, most languages are working on an implementation, most of them actually have an implementation for HTTP2 but they're not necessarily complete. For example, the go implementation is really good, it's really high quality but the push feature is not as exposed to the user just yet. If you're wondering if your language of choice actually has a library, there is a curated list by the HTTP2 guys which you can just load up and look for a language and look at the libraries that there are. If you just wanna play around however, I wrote a tool for you, which I called a simple HTTP2 server and it is basically the same thing as Python's simple HTTP server. It just serves the current directory over HTTP2, right? So this is just the same, just with HTTP2. So you can just download the binary, I have binaries for all major platforms and when you start the server, it will generate a certificate for you, a self-signed one so you don't have to worry about it because GLS is the thing, right? And once you go to the actual URL of the directory, you will see the contents or the index HTML and it will be given to you over HTTP2. But just keep in mind that this is not a production server, this is really full playing around locally and seeing the benefits of switching. So if you're interested in that, go to the Google Chrome org on GitHub and get the simple HTTP2 servers. The binaries are in the release section and you can just download one single binary, it does everything for you. Talking of production environments in the middle, I see different levels of commitment to H2 right now and they involve different levels of effort for you to put in it to actually do the switch. The simplest part or the easiest way to do it right now is the same thing that's the financial time state which is move all your static assets to an H2-enabled CDN because the biggest number of requests for a website are for assets. So removing head of line blocking just for them will already give you a great benefit. Exactly and just so you will see here on the slide that the green area is supposed to be HTTP2 and your API would still be over HTTP1. So one impact would be for example, again the image where you're over 3D, reduce the load time from 8.4 seconds to 1.8 seconds which is huge but obviously this is a test case that is tailored towards showing off the issue of head of line blocking. So if we look at a more realistic case and in this case I chose the material design light website, the impact in how much faster it loads is pretty negligible but in terms of how much data is transferred we actually save 10% of data which on mobile can be huge especially it adds up right. So as always measure the impact so you know if it's actually worth your time. To achieve commitment to H2 I would see as having an H2 enabled reverse proxy in front of your current app. Basically Cloudflare is doing this right now but Cloudflare is using speedy but it has the same kind of benefits. It basically removes head of line blocking and does the header compression for you and head of line that works because from back end to back end you don't have the limit of just using six connections. This would basically speed up your app and give you a better opportunity to do the caching on the side of the client. And then obviously the full tier commitment would be doing a full H2 deployment. You use push, you use weights, you have everything set up but as I said it's probably unrealistic to do this at this point due to the lacking server support. So to end this I kinda wanna take a quick look at the future of H2. Static hosters like Google Cloud Storage or GitHub Pages don't give you a way to specify what resources to push when somebody requests index HTML, right? So Eric Bidelman, Alex Orrin and I have been working on a manifest format that allows you to specify just that and Eric and Alex also wrote libraries to consume these manifests when you write an app on App Engine in Python or Go. So the manifest looks like this where you actually say for the index HTML I would like to push the app.css and for the page.html I would like to push page.css and you can define as many resources as you would like to. And as you can tell, it's just straight up JSON. And as I also told you, we are working on libraries in different languages to consume these on App Engine and also additionally Eric wrote an MPM package that generates these manifests for you by analyzing your HTML files which is kinda nice because that means it's just another build step instead of you maintaining these manifests manually. At some point I would like to see support for more hoses to adapt these manifests but we just came up with it so it's too early to tell. WebSockets might not be a thing anymore. I mean, they still work just as before but they are a separate protocol and therefore a separate connection. They're not being multiplexed over the H2 connection because separate protocol. So it might actually be suboptimal for you to use and since long polling is now really fine again in H2 because you are not wasting one of your precious six connections, you can pretty much emulate the same behavior over a pure H2 connection instead of using WebSockets. Time will tell if this is actually true or not. To summarize this entire thing, should you do it now? Yes, do it. Why? Because performance matters. HTTP2 really will give you benefits just by switching it on and not caring about it anymore and when you're doing that also enable compression. It's a wasted opportunity not to do this. It's almost gross negligence so I think everybody should just switching over. Be a good citizen of the internet. How to enable it? It really depends on your current setup. It really depends on how much time you can put into it and how much you really care. But in the end, if you take one thing away, look into your current setup, if it is vital for you to switch and if so, do it. And if you have any questions about this or concerns or you wanna keep shouting my name, which is fine as well, I'll be around or you can hit me up on Twitter and with that, thank you for your attention.