[MUSIC PLAYING] 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 HTTP/2. 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 TL;DR, which is switch. There really is no way for you
that this could perform worse than your current HTTP set
up, your current HTTPS setup. So what I'm saying
is basically HTTP/2. 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, HTTP/2
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 HTTP, H2,
because that is A, the official symbol
for the protocols, and Chrome Inspector,
signifies HTTP/2 in 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
gives you more possibilities to optimize your website. And I'm going to using the
generic term performance year, 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, HTTP/1 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 he
originally had in mine. 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, its 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 had basically
a few headers, a little bit of meta information
and security protocol. So in HTTP/0.9, you had
to get, post, and hat. And in HTTP/1.0 put, delete, and
our favorites, link and unlink, came through, which we
all use daily, right? [LAUGHTER] So these are more methods
that added-- not all of them were obligatory as you can tell. And that is basically what
we stuck 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 methods, which you needed to do like
cross origin communication. You had the host header,
which was now obligatory, because people start
hosting multiple websites on the same server. And you had more
control of a 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 hyper media. 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 just said, HTTP
is over 20 years old. And obviously, since we are
kind of starting to abuse HTTP/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 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, caching, and vulcanizing, and
all these kind of things that, for some
reason, we have to do to not have an abysmal
performance nowadays. And all these hacks address
problems, as I said, and the most notorious all
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 would put out a request. And you had to wait
until one of these was finished until you
could reuse the connection. So obviously, there is
kind of a bottleneck there. And we realized that,
and people said, OK, let's raise the limit. Let's go to six connections. And you can kind of realize six
is not really enough, again, and it just like postpones
the problem a little bit. The Golang guys--
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 these tiles in
the website with image tags, and just served it over HTTP/1. And as you can maybe, hopefully
tell by this graph, first of all, you see the
six connections, and the seventh one, a little
JavaScript from another server. But you see the six connections,
and sort of like 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 that with H1,
there's almost no saturation whatsoever, and with H2,
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 HTTP/1 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 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. And each of these
cookies will 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, I can compress my data obviously. Like 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
gzipped, and that's also just a missed opportunity. So at that point
people, realized that we were not using HTTP/1
for what it was designed for, and something else had to come
up, so we started doing SPDY. And we tried out a
few things, and kept the stuff that was working. And on the basis of SPDY,
HTTP/2 was specified. And this is where the
interesting part of this talk actually begins, because now we
are 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 like wrapped
differently on a binary level. The second scary part is that
H2 is the protocol upgrade. So people like to think,
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 H!, and
everything will work as before. But what is H2 really? First of all, it's a single
TLS encrypted connection. So 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 Let's Encrypt,
which is going to go in open beta
on December eighth. 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
connections is being addressed on a protocol level. So we can actually work
with a single connection. The connection itself
actually looks like this. And what used to be a request
response paid in HTTP/1 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
off 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, an
additional feature is that the client can specify
dependencies and weights for each of these streams. So 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 is
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 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 the single connection that
does multiplexing actually invalidates a lot of the best
practices we already know and how 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 website,
and you would sprite them into a big image. Changing a single
item, a single icon, would invalidate the
entire sprited image, and you have to re-download
it all over again. And now, requests are
cheap, and you can't 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. [LAUGHTER] And just keep in mind, there's
no feature being used here, except the fact that
head-of-line blocking is gone. 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 these chunk of sixes. With indentation on the
right side, we don't really. So H2 is much like
us 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 head-of-line blocking, how does this
translate into real life? And luckily, Financial Times
did an actual life test, where they moved
the static assets to an H2 enabled CDN of Akamai. And they kind of
segmented the clients into three groups, the
groups and 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, this alone, just moving the static
assets to a 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 splits
frame types of header data, and of header frames
and data frames, this is a great
opportunity, because now since your 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 its glorious
and new, it gets stars. HPACK, which is the
compression for headers, defines the notion of the
compressor and decompressor, which is pretty normal
for a compression. But the interesting thing
is that these compressors 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 want to go into
this a little bit more. So we send out a request
to example dot org, and want to get the index HTML. And the compression
works just like gzip. It's a Huffman coding kind
of, and additionally, it has a lookup table. So the first 62 entries
of the lookup table have been extracted from
the most popular websites out there, and the request
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 go 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 few bites,
indexes in the table, and then just a Huffman, a gzip, of
the string example dot org. The interesting
thing now is that, after this has been completely
transferred over the server, then values that
weren't in the table are being added to a dynamic
part of the table, which starts at index 62. So now, we actually have host
example dot org in the table. That means, once we send
out the next request, and this time we want to
post to slash something, we can reuse the
table and don't have to re-encode example dot org. However, in this
case, slash something, that's going to be gzipped, and
go [INAUDIBLE] table 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 decompressor. So having multiple connections
is actually bad for you. So you still want to
do CDN's obviously, because you want to
be geographically close to your
clients, but you want to 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 want to do multiple connections. And also, non-changing
cookies are actually highly compressible now. So what used to be kind of
[INAUDIBLE] 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 a little bit, and it gives you more room
to improve your website in terms of performance. And probably the best known
feature of HTTP/2 is push. And it is not to be confused
with the web push notification API. Push is a technology,
or something of a protocol, that allows
you to respond to requests 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, OK, here's your index HTML. He's obviously going to answer. But then a server can go and
be, OK, you got index HTML, but I'm pretty sure
you're also going to need style.css and script.js,
so here goes well with those. And those are called
push promise frames. And once the client
is 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 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 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 and 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. It's 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 SPDY, 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 to your production
environment? Ironically, at this
time, the browsers are actually ahead of
the servers for once. All the major browsers
support H2, and can now use as there is full support. That is technically not
true, because stream weights and stream dependencies
are not well supported, at least not
consistently, but HPACK and the multiplexing
protocol itself is supported across the board. And then there's still
the upgrade feature that if, for some reason the
browser doesn't support it, it's just going to stay on H1. On the server side, at
least very recently, a lot of the famous
severs have merged, or starting working on
a 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 GCP 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 implementation. Most of them actually have
an implementation for HTTP/2, 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 HTTP/2 guys,
which you can just load up and look for language,
and look at the libraries that there are. If you just want to
play around however, I wrote a tool for
you, which I called SimpleHTTP2Server Server. And it is basically
the same thing as Python's SimpleHTTPServer. It just serves the current
directory over HTTP/2, right? So this is just the
same, just with HTTP/2. So it can just
download a binary. I have binaries for
all major platforms. And when you start
the server, it will generate a
certificate for you. It self signs ones, so you
don't have to worry about it, because TLS is a thing, right? And once you go
to the actual URL, you will see the contents,
or the index HTML, and will be given to you for H2. But just keep in mind that this
is not a production server. This is really for playing
around locally and seeing the benefits of switching. So if you're interested in
that, go to the Google Chrome or on GitHub, and get the
simple HTTP/2 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, though, 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
"The Financial Times" did, which is move all your static
assets to an H2 enable 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 so you'll
see here on the slide that the green arrow's
supposed to be HTTP/2, and your API would
still be over HTTP/1. So one impact would be, for
example, again, the image where 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 percent of data, which on mobile can be huge. It adds up, right? So as always,
measure the impact, so you know if it's
actually worth your time. Future commitment to H2 I
would see as having an H2 enabled reverse proxy in
front of the current app. Basically, CloudFlare
is doing this right now, but CloudFlare is
using SPDY, but it has the same kind of benefits. It basically removes
head-of-line blocking, and does the header
compression for you. And it works because
from back into back, and you don't have the limit
of just using six connections. So this would basically
speed up your app, and give you better
opportunities to do with 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 at this point, due to the lacking
service report. So to end this, I kind of
want to take a quick look at the future of H2. Statis hoster, like Google
Cloud Storage or Pages, don't give you a
way to specify what resources to push when somebody
requests index HTML, right? So Eric Bidelman,
Alex [INAUDIBLE] and I have been working on a
manifest format that allows you to specify just that. And Eric and Alex
also rolled 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 dot css. And for the page
dot HTML, I would like to push page dot CSS. And you can define
as many resources as soon as you would like to. And as you can tell, it's
just straight up JSON. 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 m Package that generates these
manifests for you by analyzing your
HTML files, which is kind of 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 hosters 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 of 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're 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. HTTP/2 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, though I think everybody should
just switching over, be a good citizen of the internet. How to enable 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 viable for you to switch, and if so, do it. And if you have any questions
about this or concerns, or you want to 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 attention. [APPLAUSE] [MUSIC PLAYING]