 I'm actually really relieved that I can be here on stage because a few days ago it did look like I would be here I had like this massively Thor's throat and Didn't have any voice left which what you kind of need when you want to be on stage so I went to the doctor the next day and He did the whole wooden spatula flashlight thing looked and then he said. Oh, yeah, I see it And I was like what and then he grabbed a pair of pliers went into my mouth and pulled out like an inch of Bamboo fiber is splintered. I apparently swallowed it I just lodged in the back of my throat and five minutes later Everything was fine again. My throat was normal. My voice was back And I thought great then I flew here and caught a cold on the flight. I guess that is bad luck Also, if you're wondering if that story had anything to do with my talk it absolutely didn't So my name is Surma. I work with the Google Chrome team in London And I'm here to talk to you about instant loading and how hv2 ties into that whole story So instant loading you probably know the experience you have something on the home screen of your phone You tap that icon and you expect the app to be there instantly to open up and to be ready for you to work with and That is something that shouldn't have any white screens or Spinners ideally so you just want to be The app should be there right away for you to work with and I need to talk about how we can achieve that with your web apps And it's actually pretty easy you take a service worker you slap it onto your web app You make it cash everything offline enjoy your instantly loading app done end of talk. See you later Obviously my talk is supposed to be a little bit longer. So there was more of a setup However, that advice is technically correct. You can't load much faster than loading from local cash with a service worker However, how do you get all your things into the cash that the service worker uses? And with web apps that involves the network because you have to download them into the cash And then you have new bottlenecks you have the network and you have latency and all these kind of things And what do you do when some of the assets have to be updated individually? And this talk I want to talk about these kind of questions I will not even cover service worker because there's so much that you can do before service worker actually Get into the whole equation because on the first load the service worker is not there and on the first load That is your first impression. So you have to get that right too. So let's rewind or rewind a bit Yes, we want to achieve instant loading, but that includes the first load as well And with the web with the app with the web that involves the network and downloading with HTTP before the service worker is there To a certain degree all the optimizations that we're going to talk about also benefit the service worker because Loading from cash is kind of similar and however the impact will be a little bit smaller So I will talk Sorry I'll focus on the first load Because that scenario is the worst case on the web. You have nothing there locally So you have to get everything from the web if you have something cached For that resource you already removed one of the biggest biggest bottlenecks that is the network The overarching theme as you will realize of this talk is keep your assets small If your markup is small, it will be it will go faster over the wire The pauser has less to do and it will be done sooner same goes for javascript same goes for style sheets So just keep all your assets as small as possible Once we have that then we can actually look at the remaining optimizations in the instant loading problem space so to speak And as I said, I'm going to tackle this entire thing without even talking about service worker We're going to look at the features of the web platform as well as the HTTP protocol And if you don't know about the HTTP protocol All too much good news is we just launched a new Udacity course today And if you want to sign up first just go to the url that is on the slide right now You can sign up and we're going to start from zero and take you all up to the all modern things of hbt2 So let's get back to the actual talk um The assets what actually are assets well actually something like your index html The images the style sheets the javascript everything that needs to be requested as a file is an asset And if these assets are not delivered fast Your app won't be fast because your app won't work without your assets um It can't operate without them and there's a lot of opinionate discussions out there What framework to use or what css pre-processor is the right choice? And this is not what this talk is about because Whatever you choose whatever framework you choose or pre-processor The files still have to be delivered to the user. So get your infrastructure right first and all the other choices can be made after that I might be asking uh, why is instant loading important anyways? and Gabor made a really interesting observation here which talks about conversion Every step that you make your user take Before they get value out of your app Will make you lose 20 percent of your users And loading is definitely a step both for native and for web apps because you're forcing your user to do nothing to just sit there and wait And installing is actually another step and the web is great at that step because we have no install step You just open it up and you're right there while on native You have mostly have to actually install the app So if you do it right you can have much more users on your web app than a comparable native app And additionally multiple companies in the e-commerce sector have independently researched and confirmed That a reduction in load time also correlates to revenue So for example amazon has famously stated that an increase of their loading time by just 100 milliseconds Will cost them 1 percent of their revenue And that really makes you think about how much it is worth to spend time on this But let's get down to tech. Let's talk about how we actually tune our asset delivery to the max And there's a lot of facets that can be tuned and it has varying degrees of impact And require varying degrees of commitment And investment by you So let's start with something it has a very high or at least medium impact and requires almost no commitment at all And that is compression If you take one thing out of this talk, please enable compression There's a lot of sites still out there that don't do it and it is So easy to do you mostly need usually one line in your back end configuration to enable it and your content doesn't care The browser of a user can be very old. It is so good. So well supported Your logic doesn't care. It is performance for free. It is practically money in the bank And some people Say they are concerned about increasing their cpu load on the back end And I think it is only partially true Because at least for static content you can Compress ahead of time or casually compress response. We never have to compress again And if you choose to enable compression just for static assets for now, it would still be a big win for everybody involved I'm going to say big win. I actually may mean 60 to 80 data savings without you putting in any actual effort The compression ratio and you have to realize that is actually both Money safe and traffic and speed gained in loading time In general talking about this table Minification plus compression will give you a little bit better results than just compression alone If you look at css felt they will mostly have almost the same size while the gap between compression and minification plus compression Will be a little bit bigger when you talk about javascript That is mostly due to the fact that javascript tends to have comments in it Which are stripped away by minification but remain there if you only compress One of the main causes of slowness of the web today is network latency Mostly we have solid connections and rather predictable speeds But the time it takes for a byte to go from a to b and back Varies widely across the world and that has a huge impact on how your web app performs These round trips are deceptively expensive Even on a wired connection when you're visiting a highly optimized website a round trip can cost you or will cost you 20 to 50 milliseconds and with hdp that means when you send a request You can't use the connection for anything else until the response has been sent back So this is time spent waiting doing nothing And then you have to realize the average website nowadays makes roughly a hundred requests So with a little bit of back of the napkin math It turns out that when you have a hundred requests and at most six connections to the same server That means that the browser will spend at least 833 milliseconds waiting just because there is a round trip and that means that That means that shaving off a single millisecond of your round trip time is worth the effort because it has a huge impact hdp multiplies the impact of the round trip a lot And for example redirects are something I counter very often that mostly don't bring any value to the user And can be easily avoided most of the time with which for example hsts is for that emily just mentioned And on the contrary redirects can actually be even worse because they usually mean Not only another round trip but also a new connection a new tls handshake And therefore are even more expensive and just delay the user getting to your site But so far we have mostly talked about How we can make things go faster over the wire And that's good. That is really important. However, our job as web developers is not done When the data arrives on the user's device We also have to structure our app in a way that it loads fast and also is interactive as soon as possible um And interactive or visually complete is something that's absolutely psychological measurement And a screen with a few empty boxes will be much more pacifying to the user Than a white screen and if you have content above the fold actually fully run it, that's even better And that will influence the opinion of you of the user about your app very heavily And one thing that you can do very easily to increase the time to be visual Earlier is to delay your java script until the html has been parsed By default without any attributes a script tag will be blocking that means when the html parser is going through your document And it encounters a script tag The html parser will pause until that script has been executed If that script is an external script, that means the the parser will pause It will open up a new connection. It will possibly do a till as handshake. It will request the file Download the file parse the file execute the file and then the html parser can finally continue um This is actually something that will delay your render quite significantly and with the async keyword You can tell the browser is all right to keep parsing html while it is preparing the javascript to be executable And it will pause when it can finally execute defer on the other hand is even stronger That means you're fine with deferring the execution of the javascript to the point when the html is done And that means that you can be sure that the dom has been parsed has been put on the screen And you have something visual to keep the user busy while the javascript is spinning up And if you're like me and you can't remember which one is async and which one is defer just be like me and put both Because defer is stronger than async and you should always be doing defer anyway So it will be and you will end up doing the right thing can't go wrong Sadly link tags which we use to pull in css don't have support for Async or defer so But just like javascript they do block the parser. So we are kind of screwed in that regard So what do we do about css? Well, there is this tiny piece of code by the filament group that allows you to dynamically load css And that's a great tool However, be careful to not just slap it onto all of your style sheets because you will end up with flash of unstalled content Because now you have deferred everything Your html will be rendered without styles on the page and then all your styles come in and it will have like Things moving around and changing colors and it will be a really really bad experience So we have to find a good middle ground between putting everything in the head and be blocking and deferring everything and have a flash of unstalled content And good advice is here to use reasoning or critical css The common practice is to inline the styles for things that you consider critical and defer everything else This also gives you a chance to prioritize which style sheets need to be loaded next and in which order So you have more control over when bandwidth should be allocated for what job Regaining css ties into that that is the part of this css that make elements assume the size That they are going to have once the entire the the full styles have been loaded Basically, that means that you won't have elements jumping around on the page When the full styles come in because they have already assumed their their final size You could even go further and inline the styles entirely for you above the contents above the fold content To basically keep the user busy while everything out of screen is rendered later A good example for reasoning css is paul lewiski touching your app What you see on the left side is the styles that have been inlined and the markup for it is really really small and is therefore on screen very very early And then the JavaScript is being boosted up in the background and when the app is finally loaded It will look like the image on the right But this is a purely psychological trick but it makes It goes such a long way on how the user feels about this app because it feels like it's there immediately even though it is actually not Another issue is iframes iframes are a resource and that means that A page is not allowed to fire its load event until all the iframes are completely loaded themselves And if the iframe contains iframes Things get even worse Basically, what i'm saying is iframes make you lose control over your pages load event And that is bad because most libraries and a lot of frameworks Actually use the load event to know when to start working So what can we do about this you want to fire you want to have that event fire rather sooner than later Because you want your framework to spin up So if you have non-critical iframes i wrote these three lines of javascript that basically say put your Source for the iframes in a data source element And you can have this javascript run after the load event that will move the data source attribute to the source attribute And then the iframe will start loading and the load event has already fired you have gained back control Over a site however keep in mind that these iframes won't work if javascript is disabled or doesn't run for some reason So use it for non-critical iframes So as I said conserving data is probably the easiest way to make apps load fast If your app doesn't need a lot of data to get running it will be fast by very definition And that's why a good caching strategy will improve the loading times even more And I know we have service worker and with service worker you can do arbitrarily complex offline strategies and caching stories and whatever However service worker the foundation of service worker is progressive enhancement And that means that your app should also work when the browser doesn't support service worker And ideally it should even perform when there is no service worker Uh, and so I think this is a good time to look at what HTTP the protocol actually offers in terms of good caching Most HTTP responses contain both a last modified and an e-tag header The last modified error says Well when the document was last modified and the e-tag header actually contains a unique value that is solely based on the Contents of the file most server implementations actually use a checksum like sha one that is solely based on the content of the file And it will only change if the contents change And both of these headers can be used to avoid redownloading a file if there is already a cached version locally available Uh, if the browser has a version locally available It can add any of these two headers to the request basically telling the server which version it has available The browser can check and the server can check if the document has changed ever since and if not it can respond with a status code 304 that means not modified basically telling the browser to use the locally cached version available Um, and what we've just did we basically saved the user from free downloading files that they already had That is really important as you can see in the example actually specifying both headers is allowed And e-tags will take precedence over date-based headers as they're considered more robust However, it is still a request and response It is an entire round time trip So there's still a lot of time being wasted here and this is where actual hdp caching comes in caching tells the browser how long it is allowed To consider this version of the document fresh and to deliver it straight from cache without even checking with the server Expires is the older hdp 1.0 header for caching and cache control is the newer hdp 1.1 version for cache control Cache control is much more powerful and complex It supports multiple variants of different cache types like public and private You can get very granular control. It actually has its own domain specific language kind of so it's a little bit overwhelming But most of the time you should be fine with what you see on the screen right now public and the max age Which is the number of seconds until this document expires And the next question almost immediately becomes so what are good values? Should I cache my javascript for 10 minutes and images for an hour or a week? And I think jake has a really good answer here because he said with interdependent resources Which javascript and css mostly are the only sensible hdp caching options are must revalidate Or a year's worth of max age. So what does it mean? This means that something like your index html should never be cached It should always be revalidated with a server as we saw before with one of these if modified headers Something like web fonts should probably be cached with years worth of max age because they will never really change And now we are still at the point that every resource would be Revalidated with a server which is not really what we want and this is where a trick comes in where we incorporate The hash of the file into the file name and crank up the caching time to a couple of years Because the index html is your entry point It will pull in all the resources with its file name And that means whenever a file changes changes the file name changes now And the index html will pull all in this resource and the resources that haven't changed will still be in cache and Can load much faster from the local cache There's actually a gull plugin that does this for you It basically goes to your files and renames them at the cache at the the hash to the file name Uh and gives you a translation manifest that can be consumed by additional plugins that you can find in the Readme office plugin of this gull plugin to rewrite your html files or your javascript files to use the hashed versions of these files And now let's get to the highlight. Let's talk about htp2 htp2 is as the name suggests the successor of htp1 and htp2 was based on speedy an experiment by the chrome engineers Um and this picture has been passed around a lot on twitter saying a picture says more than a thousand words I personally think that picture only says more if you already know what htp2 is about So i will give you a very quick overview on htp2 The biggest improvement is probably that instead of using six connections htp2 only uses one connection and that sounds very bad at first but let me explain Basically what used to be a connection in htp1 is now considered a stream in htp2 and all streams Share that single connection A stream is broken up into frames and when a stream is done putting its frame onto the connection It because it's blocked or it has to wait or it is just done then another stream can take over So so this one connection will always be fully utilized um The problem that we had before where you send out a request And have to wait until the response came back is head of called head of line blocking because one request Blocks the head of the line of the rest of the requests that are waiting for being sent um So yeah, as I said most streams can be Uh, this the streams can utilize the connection very well And that alone is a huge improvement When you have a lot of small assets and therefore a lot of requests Um htp1 becomes unbearingly slow Which is why concatenation and spriting is a thing right now You pack up multiple assets into one big asset which you can get for a single request And unpack them on the client side because that is more efficient in htp1 So I I made this website where I split up an image into Multiple tiles basically artificially blowing up the number of requests I need to show these this tile image I just included it with simple image tags and then loaded this website over htp1 and htp2 I'll let you guess which one is which Htp1 as I said earlier heavily implies Multiplies the impact of the round time trip while htp2 does not this is an emulated 3g connection And even then htp2 seems to load instantaneously The second big improvement of htp2 is that we have frames and these frames are used to distinguish between header data and actual payload data um That is really important for us because amongst other things We can now finally Compress headers in htp1 if you enable compression only the payload will be compressed the actual body in htp2 We can now compress headers and actually the engineers went a step further and came up with their very own compression specifically crafted for htp2 The compression works on a per connection basis means that all the streams share the compressor And that is really really handy because that means if the compressor realizes it has sent a header before It will not re-send the header, but just says same header as before So some headers have never changed like host or accept or cookies will not get re-send And that will save a lot of bytes and not just bytes for most websites. It will save hundreds of kilobytes on average But most importantly in case you're scared htp2 is backwards compatible to htp1 that means if a browser doesn't support htp2 Which it really there should be no browsers out there really at this point Uh, it can fall back to htp1 And the semantics stay exactly the same too. You still have request response You still have a header section and the data section. You still have the same methods the same verbs The bottom line is just by switching to htp2 right now. You can reap most of the performance benefits without doing anything However, there's additional features in htp2 like push that do require you to do a little bit work on the back end But might very well be worth it Push is a technology in htp2 that allows you to respond to a request that hasn't even been sent yet And what I mean is I guess the best example is just your index html Somebody request your index html you respond to it, but you know that in 99% of the time They also want the main style sheet and your job is going to just send that along with it And the browser will already have it in its local cache when it realizes that it now needs those files You basically reduce the round-trim trip to zero milliseconds, which is amazing Of course pushing everything is also not The optimum for the best possible performance or the best possible experience for the user And since browser now actually have good support for push We thought it was a good time to look at how to use it right and the polymer team Actually came up with the pattern that is called prpl It is an acronym because a more acronyms that allows you to That guides you towards being interactive as soon as possible The first step is pushing the resource that you need for first render Pushing or use inlining when you don't want to use or when you can't use html You have that all in the first request So they can get on the screen as fast as possible with a response to the first request And you have the first two steps already done The next step is preloading the things that are very likely for the user to do next So for example, if you know it is very likely for my user to open up the sidebar Load the JavaScript and the styles for the sidebar and have those ready for when the user actually starts interacting with your page Or if a navigation is most likely Note the next view or the next route whatever is appropriate in the context of gap And everything else should be lazy loaded on demand There's a talk to a talk by kevin schafer from the polymer team from my own link to at the bottom Which goes into more detail on the whole topic If you want to play around with hv locally, I wrote a tiny tool, which is just like python's simple hv server But you know uses hv2 and also has support for push I wrote it in go. So there's binaries for macOS windows and linux alike in the release section This tool also takes care of Generating a certificate for you because for hv2 you always need a tls certificate, but it is taken care of in this tool for you Um and all the details you need are in the readme and the repository. So go there if you want to play around with it And this is all I have for you today Here's a little bit of a summary that of the things we talked about it was quite a lot If you have questions about this or you want to know Uh more details, I'll probably be in the colab area today or be at the office hours tomorrow Um and next up we have owen who is going to talk about to you about push. Thank you very much