Instant loading with HTTP/2 (Progressive Web App Summit 2016)
Skills:
Frontend Performance85%
Key Takeaways
Optimizing loading performance with HTTP/2 and ServiceWorker
Full Transcript
[Music] I'm actually really relieved that I can be here on stage because a few days ago it didn't look like I would be here I had like this massively Thor throat and uh 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 in of bamboo fiber a splin that I apparently swallowed that just lodged in the back of my throat and 5 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 um 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 hb2 ties into that whole story um 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 um and that is something that shouldn't have any white screens or Spinners ideally so you just want to be the app the app should be the right way for you to work with and I'm here to talk about how you can achieve that with your web apps um and it's actually pretty pretty easy you take a service recer you slap it to 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 it was more of a setup however that that advice is technically correct you can't load much faster than loading from local cach with a service worker um however how do you get all your things into the cash that the servers worker uses uh and with web apps that involves the network because you have to download them into the C 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 uh in this talk I want to talk about these kind of questions and I will not even cover server Rec because they're so much that you can do before service record actually get into the whole equation because on the first load the service record is not there and on the first load that is your first impression so you have to get that right too so let's revise rewind a bit yes we want to achieve instant loading but that includes the first load as well um and with a web with the app with the web that involves the network and downloading with HTP before the service worker is there um to a certain degree all the optimizations that we're going to talk about uh also benefit the service worker because loading from cach is kind of similar um however the impact will be a little bit smaller so I will sorry uh I'll focus on the first load uh because that scenario is the worst case on the web you have nothing there locally so you have to get everything on the web if you have something cached for that resource you already removed one of the biggest biggest bottleneck that is the network um 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 poer has less to do uh and it will be done sooner same goes for JavaScript same goes for stylesheets so just keep all your assets as small as possible um 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 uh HTP protocol and if you don't know about the HP protocol all too much good news is we just launched a new Udacity course today and if you want to sign up for this 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 hb2 so let's get back to the actual talk um the assets what actually are assets well actually something like your index HTML the uh the images the stylesheets 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 opinion 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 a 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 and you might be asking uh why is instant loading important anyways and gabber 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% 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 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 low time also correlates to revenue so for example Amazon has famous stated that an increase of their loading Time by just 100 milliseconds will cost them 1% 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 that have varying degrees of impact and require varying degrees of commitment uh and investment by you so let's start with something that 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 SES still out there that don't do it and it is so easy to do you mostly need usually one line in your backend 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 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 cash the compress response so you'd 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 and when I say big win I actually mean 60% to 80% data savings without you putting in any actual effort uh the compression ratio and you have to realize that is actually both money saved in traffic and speed gained in loading time in general talking about this table uh minification plus compression will give you a little bit better results than just compression alone if you look at CSS fils that 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 and that is Mo mostly due to the fact that JavaScript tends to have Commons in it which are Stripped Away by modification but remain there if you only compress one of the main causes of slowness of the web today is uh Network latency mostly we have solid connections and rather predictable speeds but the time it takes for a bite 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 um these round trips are deceptively expensive uh 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 spend waiting doing nothing and then you have to realize the average website nowadays makes roughly 100 requests so with a little bit of back of the napkin math it turns out that when you have 100 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 roundtrip and that means uh that that means that shaving off a single millisecond off your round trip time is worth the effort because it has a huge impact HP 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 which which for example hsts is4 that Emily just mentioned um and on the contrary rirs can actually be even worse because they usually mean not only another roundtrip 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 uh how we can make things go faster over the wire uh 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 possible um and interactive or visually complete is something that abely 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 fult actually fully R that's even better and that will influence the opinion of your 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 JavaScript until the HTML has been parsed by default without any attributes a script tag will be blocking that means when the HTML poer is going through your document and it encounters a script tag the HTML poer will pause until that script has been executed if that script is an external script that means the the paer will pause it will open up a new connection it will possibly do a TLS handshake it will request the file re download the file par the file execute the file and then the HTML paer can finally continue um this is actually something that will delay your render quite significantly and with the asyn keyword you can tell the browser is all right to keep paing HTML while it is preparing the Java script to be executable and will pause when it can finally execute defer on the other hand is even stronger that means you are 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 poed 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 uh because defer is stronger than async and you should always be doing defer anyway so will be you will end up doing the right thing can't go wrong uh sadly link tags which we use to pull in CSS don't have support for uh async or defer so but just like JavaScript they do block the P so we're kind of screwed in that regard um 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 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 regening or critical CSS a common practice is to inline the styles for things that you consider critical and defer everything else uh this also gives you a chance to prioritize which sty sheets need to be loaded next and in which order so you have more control over when bandwidth should be allocated for what job regening CSS ties into that that is the part of the CSS that make elements assume the size that they're 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 stells come in because they have already assumed their their final size um you could even go further and inline the Styles entirely for you above the contents above the fold content to basically keep these are busy while everything out of screen is rendered later a good example for regening CSS is Paul Le's guitar Juni app um what you see on the left side is the styles that have been inlined and the mark up for that is really really small and is therefore on screen very very early and then the JavaScript is being boost 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 uh a page is not allowed to fire its load event until all the if frames are completely loaded themselves and if the iframe contains iframes things get even worse uh 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 uh actually use the load event to know when to start working um 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 uh your framework to spin up so if you have non-critical ey frames I wrote these three lines of Javas rpt 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 iame will start loading and the load event has already fired you have gained better control over your s side 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 if frames so as I said conserving data is probably the easiest way to make apps 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 workers 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 server service worker uh and so I think this is a good time to look at what HTP the protocol actually offers in terms of good caching most hdp responses uh contain both a last modified and an eag header the last modified header says well when the document was last modified and the eag header actually contains a unique value that is solely based on the contents of the file most server implementations actually use checkm like sha one that is solely based on the content of the file and will only change if the contents change and both these headers can be used to avoid redownloading a file if 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 redownloading files that they already had and that is really important and as you can see in the example actually specifying both headers is allowed and eags 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 around time trip so there's still a lot of time being wasted here and this is where actual HTTP 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 cash without even checking with the server expires is the older HTTP 1.0 header for caching and cach control is the newer h HTP 1.1 version for cache control uh cache control is much more powerful and complex uh it supports multiple variants of different cache types like public and private and 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 comes so what are good values should I cach 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 hdb caching options are must validate or years 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 uh something like web fonts should probably be cashed 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 the 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 HT HTML is your entry point it will pull in all the resources with its file name and that means whenever a file change changes the file name changes now and the index HML will pull all in this resources 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 Gul plugin that does this for you it basically goes to your files and renames them adds the cache at the hash to the file name uh and gives you a translation manufact that can be consumed by additional plugins that you can find in the readme of this plugin of this G 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 http2 htb2 is as the name suggests the successor of hp1 and HD2 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 hb2 is about so I will give you a very quick overview on hb2 the biggest Improvement is probably that instead of using six connections http2 only uses one connection and that sounds very bad at first but let me explain basically what used to be a connection and http1 is now considered a stream and http2 in 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 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 the the streams can utilize the connection very well and that alone is a huge Improvement when you have a lot of smaller assets and therefore a lot of requests um hb1 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 with a single request and unpack them on the client side because that is more efficient in hb1 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 T image I just included it with simple image tags and then loaded this website over HD1 and HD2 I'll let you guess which one is which HD1 as I said earlier heavily implies uh multiplies the impact of the roundtime trip while hb2 does not this is an emulated 3g connection and even then hb2 seems to load instantaneously the second big Improvement of hb2 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 haors in hp1 if you enable compression only the payload would be compressed the actual body in hb2 we can now compress headers and actually the engineers went a step further and came up with their very own compressions specifically crafted for hb2 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 resend the header but just says same header as before so some headers have never changed like host or accept or cookies will not get resent and that will save a lot of bites and not just bites for most websites will save hundreds of kilobytes on average but most importantly in case you're scared hb2 is backwards compatible to hp1 that means if a browser doesn't support hb2 which it really there should be no browsers out there really at this point uh it can fall back to hb1 and the semantics stay exactly the same too you still have request response you still have a header section and a data section you still have the same methods the same verbs the bottom line is just by switching to hb2 right now you can reap most of the performance benefits without doing anything however there is additional features in atp2 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 hb2 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 requests your index HTML you respond to it but you know that in MO 99% of the time they also want the main style sheet and your JavaScript so 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 Tri trip to Z Mill seconds 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 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 uh it is an acronym because yay more acronyms that allows you to uh that that guides you towards being interactive as soon as possible but 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 hb2 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 it's 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 your app and everything else should be lazy loaded on demand there's a talk to a talk by Kevin sha from the polymer team from my that I'll link to at the bottom uh which goes into more detail on the whole topic if you want to play around with HB locally uh I wrote a tiny tool which is just like Python's simple HB server uh um but you know uses hb2 and also has support for push uh I wrote it in go so there's binaries for Mac OS windows and Linux alike in the release section uh this tool also takes care of uh generating a certificate for you because for hb2 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 read me 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 the summary that of the things we talked about was quite a lot um if you have questions about this or you want to know uh more details I'll probably be in the collab area today or be at the office hours tomorrow um and next up we have Owen who is going to talk about you about push thank you very much [Music]
Original Description
ServiceWorker give you a variety of levers over the loading performance of your app. But HTTP already allowed you to speed up the loading of your app – and these two technologies stack, so you should know what you have at your disposal. With HTTP/2, things only get better. This talk will summarize, the past, the present and the future of protocol-level optimizations.
Subscribe to the Chrome Developers channel at http://goo.gl/LLLNvf
Music by Terra Monk: https://soundcloud.com/terramonk/pwa-amsterdam-2016
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from Chrome for Developers · Chrome for Developers · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
Polymer Performance Patterns (The Polymer Summit 2015)
Chrome for Developers
Polymer Power Tools (The Polymer Summit 2015)
Chrome for Developers
Chrome Dev Summit 2014 – Chrome Case Studies
Chrome for Developers
Web Directions Code 2015 round up
Chrome for Developers
Maintainable Code - HTTP203
Chrome for Developers
iron-ajax… wat?! -- Polycasts #26
Chrome for Developers
The Guardian - Supercharged
Chrome for Developers
ES2015 (next version of JavaScript), Totally Tooling Tips (S2 Ep1)
Chrome for Developers
#AskPolymer: Rob answers all the questions ever -- Polycasts #27
Chrome for Developers
The Future of JavaScript - HTTP203
Chrome for Developers
Data Binding 101 -- Polycasts #28
Chrome for Developers
The Guardian part 2 - Supercharged
Chrome for Developers
The Future of Web Audio: with Chris Wilson and Chris Lowis
Chrome for Developers
Chrome 46: New motion-path animations, client hints and service worker improvements
Chrome for Developers
Sublime Snippets, Totally Tooling Tips (S2 Ep2)
Chrome for Developers
#AskPolymer: How do you make the show? -- Polycasts #29
Chrome for Developers
Critical Path CSS, Totally Tooling Tips (S2 Mini Tip #1)
Chrome for Developers
Binding to Objects -- Polycasts #30
Chrome for Developers
Player FM - Supercharged
Chrome for Developers
Where’s the Designer? #AskPolymer -- Polycasts #31
Chrome for Developers
Jake Beats Wikipedia - HTTP203
Chrome for Developers
Supercharged Observers! -- Polycasts #32
Chrome for Developers
Jai's Web blog - Supercharged
Chrome for Developers
Windows Command-line Tooling, Totally Tooling Tips (S2, Ep4)
Chrome for Developers
What about internationalization? #AskPolymer -- Polycasts #33
Chrome for Developers
Developing for Billions (Chrome Dev Summit 2015)
Chrome for Developers
Google+ Performance Improvement Comparison
Chrome for Developers
Deploying HTTPS: The Green Lock and Beyond (Chrome Dev Summit 2015)
Chrome for Developers
Progressive Web Apps (Chrome Dev Summit 2015)
Chrome for Developers
Instant Loading with Service Workers (Chrome Dev Summit 2015)
Chrome for Developers
Increase Engagement with Web Push Notifications (Chrome Dev Summit 2015)
Chrome for Developers
Engaging with the Real World: Web Bluetooth and Physical Web (Chrome Dev Summit 2015)
Chrome for Developers
Asking for Permission: respectful, opinionated UI (Chrome Dev Summit 2015)
Chrome for Developers
Polymer - State of the Union (Chrome Dev Summit 2015)
Chrome for Developers
Building Progressive Web Apps with Polymer (Chrome Dev Summit 2015)
Chrome for Developers
Introduction to RAIL (Chrome Dev Summit 2015)
Chrome for Developers
DevTools in 2015: Authoring to the max (Chrome Dev Summit 2015)
Chrome for Developers
RAIL in the real world (Chrome Dev Summit 2015)
Chrome for Developers
#ChromeDevSummit talks are up - W00T! -- Polycast #34
Chrome for Developers
V8 Performance from the Driver's Seat (Chrome Dev Summit 2015)
Chrome for Developers
Quantify and improve real-world RAIL (Chrome Dev Summit 2015)
Chrome for Developers
Owning your performance: RAIL (Chrome Dev Summit 2015)
Chrome for Developers
HTTP/2 101 (Chrome Dev Summit 2015)
Chrome for Developers
Leadership Panel (Chrome Dev Summit 2015)
Chrome for Developers
Build Processes, Totally Tooling Tips (S2, Ep 5)
Chrome for Developers
Accessibility (Chrome Dev Summit 2015)
Chrome for Developers
Binding to Arrays -- Polycasts #35
Chrome for Developers
HTTP2 - HTTP203
Chrome for Developers
Chrome 47: Splash Screens, requestIdleCallback and better desktop notifications (New in Chrome)
Chrome for Developers
Call For Submissions - Supercharged
Chrome for Developers
Cross Device Testing, Totally Tooling Tips (S2 Ep6)
Chrome for Developers
Testing AJAX with Web Component Tester -- Polycasts #37
Chrome for Developers
Slack: Extended Xmas Special - Supercharged
Chrome for Developers
Browser testing with Travis & Sauce Labs -- Polycasts #38
Chrome for Developers
Optimize for production with Vulcanize -- Polycasts #39
Chrome for Developers
Highlights from Chrome Dev Summit 2015
Chrome for Developers
Chrome 48: Custom buttons in notifications, DevTools Security panel, and Presentation mode
Chrome for Developers
Crisper: Protecting your Polymer app with CSP -- Polycasts #40
Chrome for Developers
How do I use Sass with Polymer? #AskPolymer -- Polycasts #41
Chrome for Developers
Colors – DevTools Tonight #0 (Pilot)
Chrome for Developers
More on: Frontend Performance
View skill →Related Reads
📰
📰
📰
📰
Why SnapDOM Beats html2canvas for DOM-to-Image Capture
Dev.to · Juan Martin
I built 42 landing page templates as single HTML files (no npm, no build step)
Dev.to · Segcam spa
Part 7B — Section 2 — React Event Handling Explained: Forms, Event Object & User Input.
Medium · JavaScript
Stop Using window.resize for Everything: A Practical Guide to the ResizeObserver API
Medium · JavaScript
🎓
Tutor Explanation
DeepCamp AI