ssible 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 HTTP 2 So let's get back to the actual talk 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 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 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 you might be asking why is instant loading important anyways and Garber 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 a native you have mostly have to actually install the app So if you do it right where 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 a hundred 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 it have 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 cash to the compressed 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 gonna say big win. I actually may mean 60 percent to 80 percent 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 And 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 a 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 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 HTTP 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 HB 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 HST as 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 and Interactive or visually complete is something is absolutely psychological measurement and a screen with a few empty boxes Will be much more pacifying to the user Then a white screen and if you have content above the fold actually fully read it It'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 JavaScript 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 bra at the parser will pause it will open up a new connection It will possibly do a tail as handshake it will request the file Download the file parse the file execute the file and then the HTML parser can finally continue This is actually something that will delay your render quite significantly and with the async keyword You can tell the browser is alright to keep parsing HTML while it is preparing the JavaScript to be executable and 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 a 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 the CSS that make elements assume the size That they are gonna have once the entire 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 Regaining CSS is Paul Lewis's guitar to your app What you see on the left side is the styles that have been in lines and the markup for it is really really small And it's 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 do 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 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 char 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 there is already a cached version locally available 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 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 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 a server expires is the older HTTP 1.0 header for caching and Cache control is the newer HTTP 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 comes so what are good values? Should I cash 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 HTTP caching options are must revalidate 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 Something like web fonts should probably be cached with years was worth of max edge 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 change changes the file name changes now and the index HTML will pull all in this resource and the resource 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 through your files and renames them at the cache at the the hash to the file name And gives you a translation manifest that can be consumed by additional plugins that you can find in the read me 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 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 this one connection will always be fully utilized 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 a line of the red stuff the requests that are waiting for being sent So yeah, as I said most streams can be 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 htp1 becomes unbearably slow, which is why Concatenation and sprouting is a thing right now We 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 htp1 So 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 Hb2, 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 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 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 hb2 We can now compress headers and actually the engineers went a step further and came up with their very own compression 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 Resent the header, but just says same header as before So some centers have never changed like host or accept or cookies will not get resented 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 Hb2 is backwards compatible to hb1 that means if a browser doesn't support hb2 Which it really there should be no browsers out there really at this point It can fall back to hb1 and The semantics stay exactly the same to 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 hb2 right now You can reap most of the performance benefits without doing anything However, there's additional features in hb2 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 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's 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 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 html2 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 your app and everything else should be lazy loaded on demand There's a talk to a talk by Kevin chef from the polymer team from my own a link to at the bottom Which goes into more detail on the whole topic? If you want to play around with HP locally, I wrote a tiny tool, which is just like Python's simple HP server But you know uses HP to and also has support for push. I Wrote it and 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 HP to you always need a TLS certificate, but it is taken care of in this tool for you And all the details you need are in the read me in 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 More details, I'll probably be in the co-lab area today or be at the office hours tomorrow And next up we have Owen who is going to talk about you about push. Thank you very much Hi, my name is Owen and I'm a product manager on Chrome's push notifications So just before we get started I feel like now would be a good time to clarify that we actually have two new features in browsers both with the name push I think it said that there are three hard problems in computer science caching no to two hard problems in computer science caching naming things and off by one errors And so I think we've fallen into the naming things trap here So this HTTP to push which allows servers to send down data to the client before they even expect it when rendering a page And then we have web push notifications, which are about sending notifications to our users And that's what we'll be focusing on today So I'm super excited that we're all here in this room full of amazing web developers And I think at last count five different browser vendor teams To talk about progressive web apps These are web apps that are reliable fast and engaging and I'm going to be focusing on the third point today Engaging specifically sending push notifications to your users So push notifications on mobile aren't anything new But I'm really excited that we finally have access to these as web developers I'm sure there are a number of you out there that have built great Mobile web experiences and then had to wrap it in some kind of Cordova wrapper and suffer the friction of an app store Just so you can get that notification capability. So our shackles are now free. We can now go ahead and do this I think that's really exciting especially when you look at when you look at the Services and apps that have been successful on mobile and just look at the top ones and think about how many of them are Fundamentally successful in part because of push notifications And we now have the ability to take advantage of that in the web And so there's a bunch of new opportunities that have emerged here that I'm excited about and This can be really huge for business as well For example, if we take a look at Jumia, which is a leading e-commerce company in Africa They had a problem and their problem was that one quarter of their users were adding items to their cart But they're not actually checking out. They were abandoning that cart and the site tried to deal with this by sending those users Emails and reminding them but getting a user to type that email in on a tiny screen is really difficult And then the open rates on those emails were extremely low So it's still early days But Jumia have implemented push notifications on the mobile web and they found that their notifications get a 38% open rate by users and that users that have enabled web push notifications Convert on those previously abandoned carts at a nine times higher rate. And so I think these kind of results are really exciting Okay, so push notifications is this amazing new superpower that we have on the web But everybody knows that with great power comes great responsibility So this begs the question. What makes a great engaging notification? and So we believe that great notifications are timely they're relevant and they're precise and So for these penguins here a push notification letting them know that there's a leopard seal behind them would really change the course of their day And so as you're designing your push notifications flows Just think about whether what you're sending is important enough to warrant an interruption Would you want to be walking down the street and fill your pocket vibrate and really use that to guide you and So let's break this down further. I said notifications work great when they're timely So try and use notifications primarily for time sensitive events, especially if these are synchronous events that involve another user For example being sent a chat message there's another person out there waiting for you to respond and it's something that you care about and It's important that you see it within the right time. So that's a great use case Calendars is another fantastic use case, you know, you're about to be having a meeting You need to know where you're going and and be reminded to go there. So timely is really key Secondly being precise notifications should contain all of the information that a user needs to understand What just happened and to take action on it if possible and Thirdly relevant, it's important to users that the notifications they're seeing are from people that they care about and about things that they care about Okay, so let's give this a go Here's one example notification. What do we think about this? I think this is pretty good, right? It's timely You know, I'm probably at the airport and I'm about to get on a plane. It's precise It tells me my flight number. It tells me when the flight has been rescheduled to and it's relevant It's my plane. It's my flight. It's super important to me. So I think that's great How about this one? Your credit card has been compromised Well, I think this could have done better, you know be minus on our on our scale So it's timely. It probably just happened and it's relevant, right? It's my credit card But it's not very precise which credit card. Why was it compromised? What's going on? What action do I take? And so if we reimagine this notification? We can add some extra information let the user know that a suspicious transaction has occurred and give them buttons that let them take action and Provide feedback to the bank Okay, how about this one awesome chat app? You have a new message So awesome chat app your notifications are not so awesome It's probably timely. I expected a message was sent to me But it's certainly not precise and who can say if it's relevant, right? Who knows? So we redesign this and we get Jake says I heart service workers Instantly, I think that should be an award for getting his profile picture in the most number of talks today I think he's maybe at three or four so far So that's a great way to redesign this How about this one? As a side note, I think if Google does launch a self-driving car service, we should definitely call it goober And so this one is great. It's timely. You know my car is arriving. It's precise It's telling me where it's arriving at and it's relevant. It's my car. I'm gonna get in and drive away and Then here's probably the worst possible example I could conceive of this is none of the above and the risk here really is that if you send notifications to your users That don't provide them value that distract them or spam them They're gonna turn off notifications and then you're gonna lose the ability to get the value from that interaction in the future Okay, so we've talked a bit about the kind of notifications which are good for our users So now let's take a look at the flow and really how this works on a high level So push notifications on the web is built on service workers This is probably a theme that you're seeing emerging throughout the day I think it talks to it talks to how service workers are becoming this fundamental Capability that are allowing us to extend the platform in all these new and interesting ways And so once you get everything set up, which we'll go into Sending a push notification the flow is roughly that your site first makes a network request to a push of a push subscription endpoint and That's managed by the push server which then magically wakes up the user's device and Manages to fire an event into their service worker and Then that service worker runs some code and it uses the notifications API to show a notification to the user So let's break that down a little more the first thing that happens When a user lands on your site is you have to check if the user is already subscribed so you know whether to show them the opt-in flow Once you've checked if they haven't already to opt it in you just wait until it's a good time Maybe the user has just done a search for flights and you give them a button that says get notified when the price drops And then once the good time comes you ask the user to subscribe You explain the feature to the user that they're opting into and then you eventually show them put the permission request and Then once you've subscribed the client it generates a subscription object You'll then pass that subscription object up to your server and save it somewhere in a database and Then on your server when you're ready to send a message you just generate the message You send that message to the endpoint that you were given previously and that endpoint Essentially the push servers keep a persistent one persistent connection open with the device And then they use that connection to tell the device to wake up the browser Wake up the service worker and so this part is special because it means that we're sending push notifications But the browser doesn't even have to be running on the device the site doesn't still have to be open It doesn't use much power And so it's a really great performance feature as well and Then the push message is received by the browser and when the push arrives in the browser It wakes up the service worker and fires an event into it your code then handles that Event and decides what to do and shows a notification to your user easy, right? Okay, so now let's take a look at subscribing for push and when you should prompt your users to opt in to get push notifications So I think that this step is super important because if you're going to be successful with push notifications You have to get users to turn them on in the first place And so it's really important to focus on this step in the process And I think it's important to be clear and intentional and treat this like any other part of your UX process The key is not to just add a permission prompt on page load without thinking about it So make sure that the user understands why they're being asked make sure that they understand what they're opting into And so we'll take a look at an example of the weather channel So the weather channel have built this page where you can choose to enable Push notifications and control some options. So I think this is great because It's specific, you know, you have this page where you know what's going on You have all of the context that you need and the permission request itself is user initiated So when the user goes ahead and checks that box saying activate browser notifications They see a permission request no surprises, right? They're very likely to click through at that point. So that's great And we think it's really nice how they give users options I can opt into breaking news or government issued alerts If you're never sure about what users going to want to enable just give them options and let them decide Okay, so we've talked about this on a high level and we've talked about UX Let's take a look at the code and how we actually are subscribed for push notifications So the first thing I said that we do is we check whether the user is already subscribed And because these are progressive web apps The first thing that we do is verify that service workers are available on this client If the service worker is available We go ahead and register our service worker if a service workers already registered This will just return with the registration object of that service worker And then we can call push manager dot get subscription to get a push The existing push subscription for the user if one exists and so now we know whether that's subscribed or not We can store this in a cookie use it later Or use this to decide whether to show them an opt-in flow Okay, now we're deciding to subscribe the user for the first time So again, we're going to get the registration of the service worker that we've registered and then we call push manager dot subscribe Essentially, this is setting up that connection with the with the push server So it knows how to talk to this client It knows that this service worker wants to be able to be woken up and then there's a option here Which has user visible only true Essentially what we're saying here is we're promising to the browser that when we send a push message down to the device And our service worker runs in the background that the user will see something So we'll either show them a notification or maybe if they're already looking at the the web app Then we don't need to do that and the idea here is Allowing making sure that Browsers can show that permission request saying this site wants to send you notifications Not this site wants to run in the background permanently on your device silently and use all of your battery So that's why that exists and then once you've subscribed actually when you call subscribe That will that be the point where that permission request is shown to the user and if they accept that request the promise resolves and We get back a subscription object, which we can then send to the server And of course we catch the case where they deny and we can decide what to show them in that case So I recommend you all check out the propel sample code up on the Google Chrome Section of github and this shows some great sample code to manage those subscription states gives you a really nice API to manage them Okay, so next once we've subscribed. I said you get that subscription object. What is that? What does that look like? So this is how it looks it essentially gives you all of the information that you need to Identify the user to the push over so it can wake up the right device It starts with an endpoint. This is like a magic URL It acts kind of like the user's phone number or email address But for push notifications is a way of identifying and reaching out to them It starts with the URL of the push service that this operating system uses in our case here Google Cloud Messaging and Then it has a long string of random letters that identify the the current user to that push service It also includes a bunch of encryption keys And this is so when you're sending data down to the user's device So you know what notification to show that message can be encrypted and can't be read by anyone in the middle Okay, so let's take a look at sending that message from the server There are two ways that you can send a Notification firstly, there's what we call a tickle. This is essentially a push message which arrives with no data So the service worker gets an event that says a push message arrived But it doesn't get to find out what happened And the second kind is push with payload. This is why you include data You let it know what happened on the server and why it's being woken up And if you're sending payload, it's encrypted with the keys that we talked about earlier And so let's take a look at actually sending those Just before I do it's worth calling out that the sample code I show here is for using the web push protocol So the web push protocol is about to start working around now in Chrome But as the standard's been evolving and implementation has been evolving It hasn't been the exact same implementation in older versions of Chrome So there'll be a link at the end which shows you how to do a backwards compatible implementation But I'm gonna focus on the future facing and what's really going to be happening from now So when your server wants to send a push message to the user The it sends a request which looks roughly like this. It's a put request to that endpoint. We were given earlier It has a time to live which essentially tells the push server How long should you keep trying to send this to the device for and you know give up if it's taken more than two minutes? It includes a content type and encoding And then it includes the public key and salt used to encrypt the message a vapid signature and the encrypted payload I'm not going to go too much into the details on those last Encryption aspects now, but again, there'll be a link at the end which gives you the full breakdown of how this works And at this URL you can find sample projects to handle the encryption and message sending on the server side we have them in Java in In Node.js in Python So go and take a look. This is kind of contributed by the open source community There are contributions also from Mozilla and from Google and there are really great set of Libraries that look at you up and running Okay, so now we've worked out how to subscribe the user and send a push message But how do we receive it on the client? What does the service worker do? So in your service worker, you just add a new event listener for a push event When that event fires You call this magic This magic method called wait until so wait until I had to look at this a couple times the first Times I was trying this wait until essentially says I'm going to run some code for a while. It's kind of asynchronous And I'll let you the browser know when I'm done and when I'm done you can go ahead and kill my service worker I don't need to be kept running. So this allows us to be very performant and efficient and You basically pass in to wait until a promise and you resolve that promise when you're finished doing the work when you've Showed the notification So here we go ahead and we just generate a notification and this returns that promise that will resolve when it's been shown So the browser can kill the service worker at the right time But actually if you look here this notification, I'm showing basically breaks all the rules we talked about earlier, right? It's static. It doesn't say anything useful So how do we read the payload? How do we know what was supposed to be showing the user? It's pretty simple. So you just check if event dot data exists If it does you call dot Jason to convert it into a JavaScript object if it doesn't exist Then that's the point where you want to make a fetch request to your server to ask. Hey, what happened? What should I be showing the user and then once you have that data you again? Just call show notification with the correct title and the body and note in this case that We actually need to return that show notification to the event to wait until to make sure that the browser knows That were that we were still doing work if you don't do this You might notice in Chrome that you get a little notification saying this site updated in the background That generally happens if you resolve the promise to wait until before you show the notification Because that's chrome checking saying hey, did you show a notification? Oh, they didn't we'll show one on their behalf to make Sure the user knows that's the user visible only true thing coming into play So we also have support for action buttons on Web push notifications these make it easy for users to complete a task without even opening the app here We can see that a user can confirm their reservation You could also use this to have users like or retweet something to pay a bill increase their bid on an auction as many interesting opportunities there and Using action buttons is super easy in the show notification call You just pass in an actions object and you give the title the icon and this action string key thing That we're going to use to recognize when the user taps on one of those buttons So then if you use it does tap on a button or on the notification a notification click event will be fired And that's where we'll say hey if the action was like then We'll reach out to the server and let it know that it was liked And if there's no action then we know that they just tapped on the notification in this case We're just going to open a new tab to the notifications page on the server Okay, so we're almost there. We're just going to wrap up now And I don't think that we can do this talk without talking about browser support. So It's worth noting that web push notifications are already supported today in Chrome and Firefox I was excited to see the opera shipped web push notifications last week Samsung browser shipped web push notifications earlier in this browser 4.0 and I read last week that the edge team have just announced that they're currently implementing push notifications on the web and At this point you might be looking at that and saying that looks great But there's maybe one missing that we care about you know, what do we do and I think that there's a big takeaway here, which is that Progressive web apps are fundamentally progressive. So when you invest in your web experience You make the experience better for your users everywhere and If you use progressive web app features in the browsers that support those features It's going to be even more awesome And this actually turns out to be true when you look at the data Earlier this year Ali express a very big e-commerce company rebuilt their site as a progressive web app And in Safari they saw an 82 percent increasing conversions on average And that's a browser that doesn't currently support service workers in these new features But I think it just goes to show that there's a huge opportunity in investing in the mobile web And if you build a great progressive web app like they did you can get that value across all of the browsers and even more value in the Browsers that support these features Okay, so we're gonna build better engagement on the web using web push notifications We're going to send notifications that are timely precise and relevant Just think about these things and ask yourself would I want to receive this notification? And my users going to be delighted by this experience We should make sure to ask for permission in context So the user knows what they're signing up to and they're likely to click through because they see the value proposition in what you're giving them and Be awesome, you know, we have these new amazing superpowers Use them to build awesome amazing new experiences for your users that you're going to love Your company is going to love and that they're going to love And with that I'm going to leave you with a few links where you can read more about this We have a guide for getting started with push notifications and then some details about the encryption aspects Tomorrow we'll have some code labs where we'll go through some of this stuff and coming soon on Udacity There'll be a course there so you can learn about that if you're watching from home so thank you very much and I'm actually really excited to be the person that gets to tell you that it is now lunch time So you can go around and back. There'll be lunch also up on the mezzanine level and we'll be starting back The next talk will start at two o'clock. So make sure that you're in here at about 150 so you can be ready on time. Thank you When you're building an app that needs to store and share data from a server There are a lot of things that you'll need to keep in mind Setting up and maintaining a database can be a hassle and if you want your data synchronized in real time or need Offline support. Well now you're talking some serious time commitment But with the Firebase real-time database you can get that time back The Firebase real-time database lets you store and sync data between your users in real time This makes it easy for your users to access their data from any device web or mobile and it helps your users Collaborate with one another Whenever you update data in the real-time database it stores the data in the cloud and Simultaneously notifies all interested devices in milliseconds The real-time database is also optimized for offline use Whenever a user loses their connection the database SDK Uses a local cache on the device to serve and store changes This means that when the user comes back online their local data is automatically synchronized and How do you keep your data secure? You can use database security rules to specify who has access to what pieces of data and how your database should be structured The security rules are securely stored with the real-time database on our servers So if you want to make sure your users can only access their own data or ensure that their message is no more than 141 characters you can do that in just a few lines of code Getting started only takes a few minutes The Firebase real-time database is hosted for you in the cloud. So there's no server maintenance or operations And there are SDKs for Android iOS and JavaScript to get started with the real-time database Check out our quick start which will get you up and running in minutes. We can't wait to see what you'll build with Firebase Hey there polycasters Rob here welcome back to the show So it's been a little while since we last talked in the previous episode We started off a series using carbon route to build an application and actually since we did that episode the Palmer team has Renamed that element to app route So we're gonna picking up where we left off last time this time That we'll be using app route to continue working on our blog And what we're gonna do is we're going to make sure that we can lazy load content on this blog And we can also manage the flash of unstyled content that we see when we switch between pages on a slower connection So to to grok what I'm talking about here Let's switch over to the laptop and you'll see that I've got the the blog as we left it last time showing here and I'm going to just go over to the the network panel and I will click this tab right here And this will let me actually throttle my connection down. Let me zoom in on this a little bit So it's easier to see so I'll go to the network tab I will go over to right over here where it's just throttling and we can set our connection to something like regular 3g So this is what someone on a typical cell phone connection. It's gonna experience when they're trying to use our site So maybe I go and I click on the film section and maybe I go and click on one of these When these posts and I go back to the art section and you just see how there was kind of like a like a moment Where we saw a flash of the old film section when we switch to the art section That's kind of the thing that I want to address today I want to deal with that flash of unstyled content Make sure that when our users are are using our application The only thing they're seeing is kind of the the relevant page and something that's really fresh and up to date So to do that we're going to switch over to our code editor and this is where we left the project last time and I've already gone ahead and Renamed and and downloaded our app route renamed it throughout our project So we don't have to do anything there any place you see carbon route in the old project We can just update that to app route the API and everything is still essentially the same just kind of a small name change So thankfully we don't have to do a lot of work there now one thing that we do need to do Which I noticed in the previous episode is I made a little mistake in this blog app element So if you see down here when we set up our iron selector menu in the previous episode as passing category data as this two-way binding like this and While this you know is cool in it this this this approach did actually work What was happening was it was creating this weird situation where when you clicked on this binding because it was a two-way binding What happened was first it would look down at this data page element and it would say Oh, you're trying to go to the film section. So I'm just going to update carbon location to slash film Then it would see that well actually we clicked on an anchor So we want to go to slash film slash list and say, okay, cool Well, I'll update it to slash film slash list now What would happen then is we would change the URL twice really really fast so fast that no one would notice it If they're just looking at the site, but if you hit the back button, it would go back to slash film We don't actually have a film page. So everything would just break So the fix there is pretty simple what we want to do is we just want to change this to a one-way binding So basically the menu always gets its information passed down to it from carbon location And you know if you click an anchor or something it'll dispatch that event I'll go back up through carbon location back down to our elements. This is nice one-way loop and that solves that bug now the next thing we want to do is we want to tackle that funky weird flashy one-styled content and There's two things that are going on here. The first is I'm loading new JSON for the page So our text is going to swap and the second is we're loading new paths for our images And those actually have to go out and fetch the images and sort of redownload them So I want to tackle each of these problems individually I'll start with you know what to do so we don't display kind of like stale or outdated text and my thinking here is I'm probably going to display like an overlay over the screen with like a little spinner So that way, you know, the user doesn't see like a weird swapper with our headings They just see a spinner page and then when that content is finally ready It just sort of reveals the new heading and the new paragraph content So to do that I'll go over to this blog pages element and I'm just going to go ahead and drop in a div I'm going to call this overlay and inside of here. I will drop in a paper spinner and I'll just leave it with this this active attribute and I need to go up to the top and make sure that I have imported paper spinner. Okay, so far so good there and then I'm going to Go to my overlay and I want to give it some CSS style. So it's actually like full screen. So Going to drop in a little bit of CSS I've already got the CSS save because I'm totally cheating here and I'm going to boost this up a little bit So you can read it a bit easier Okay, so here. I'm positioning the overlay. So it's absolute Top left right and bottom are all zero. So it's actually going to stretch to fill the entire screen I'm saying it to display flex and setting flex direction to column and align items and justify content to center center And that basically means that paper spinner child that I added there is just going to be Vertically and horizontally centered right in the middle of the screen And finally, I'll set the background to an opaque white so it hides whatever page content is behind it So we can actually just verify that this is working I can go back over to the blog that I was working on I can probably go ahead and close the dev tools and refresh the page Right. So now we're just seeing that overlay and that spinner. It's blocking all the page content So I at least know that that is working But I only want this to display When we have a page that is kind of in a loading state So what I'll do next is I'll go into my list page element I remember list page is the one that lists all of our individual blog posts I'm going to give it a loading property. So down here in its properties We have active for when the the page gets swapped to by our route But it could still be in a loading state then so at a loading property. This is also going to be a Boolean the value is going to default to false and I'm going to set it to notify true because I'm going to need to have the outside world listen to this as well so Next I'll go up to my iron Ajax element now This is the one that's sort of loading all of our blog post data for this page And it actually has already inside of it iron Ajax has a loading property So here I can just bind my loading property to its loading property, right? So that's pretty nice So now this page can kind of tell the outside world when it's loading and really what it's doing is It's just sort of telling the outside world when iron Ajax is loading So back in blog pages, which is sort of the common parent of all these guys I will add a Property or an attribute here.  So I can do that here Now down in my overlay what I'm going to do is I'm going to bind the state of the overlay to that loading property So we'll say okay, we'll use the HTML hidden attribute I use the dollar sign binding so I can bind right to the attribute itself and we'll say that This is one of those fun double negative things. So we'll say When is loading is false? Hidden should be True. Yes. Okay. So when is loading is false? Hide the overlay when we are not loading hide the overlay Okay, this is one of those like things where you got to think about it for a second And then the active state of our spinner. We're actually going to do the reverse We're gonna say, okay. Well, if it's loading then we do want the spinner to be active. Okay So that means now as we switch back and forth between the list page We should see that that overlay for just a second and when all that content comes in from iron Ajax It should hide itself. I'm gonna go ahead and then and actually do the exact same thing for my post page So I'll give it a loading property as well right spoolie in Defaults to false and we want to notify true So we combine to it and we will also bind it to the loading property of iron Ajax And I can sort of duplicate that work that we did for list pages over in post page at this point, you know You might be saying These pages the sort of the signature of them is looking very very similar in our markup so it might be a good time to consider perhaps rolling some of this common behavior into a Behavior I should say so actually sharing that functionality between the elements instead of duplicating the code in both Places, so that's something that we might do in a future episode just to kind of like tidy things up a bit But for now, let's just verify that this works So I'm gonna switch back over to my browser I will refresh the page zoom out a little bit so we're pretty zoomed in there and What I can do is Because this content is gonna load in really fast because I have it local I'll go back to my network panel and I'll throttle the connection way down. So I'm gonna set it to gprs and Now when I click on film, I should see that loading state for just a second now You notice that my image still did that weird swap a roofing But we're not seeing any stale text when we go and click on these items One thing that does happen though when we switch between these is we can actually still scroll the page While that overlay is displayed and that's kind of a bummer. We definitely don't want that So I'm gonna add one more little trick to blog pages. I'm gonna add an observer for is loading So my observers array It's more space down here. So I'll create an observer for we'll say we're gonna lock scroll Whenever is loading changes And lock scroll will just be a method that I define where we say alright What is the state of is loading and if is loading is true Then we're actually we're gonna cheat here. We'll reach outside of ourselves go to document dot body and set the Overflow style to hidden if is loading is true and what that's gonna do is that's gonna like chop off the page And that way the user won't be able to scroll and see that content underneath there Otherwise if is loading is false, then we'll set document body style overflow to Visible I think is the correct value. I'll double check and swap back over and Bust out our dev tools so we can throttle this thing again. So refresh the page. Alright so far so good We'll go to our network panel. We'll set throttle lane to gprs And now we'll click on like the film section and you notice my scroll bar even like goes away So I can tell I can't scroll or anything Until that content actually has loaded in Okay, cool So we handled the issue of the text being stale and that loading in but now we still have these Images and this is a really tricky problem because when our data loads all it's loading is a path to a new image But we still have to go make that HTTP request to fetch that content and that could take a super long time to load But I don't want my user to you know be waiting when they could be reading the text of the article while they still wait on that image To load so we could kind of do a little trade-off there We give them the text of the the article But maybe we serve like a like a downgraded image So something loads faster and then we wait and kind of upgrade that image as the nicer version loads in So let me do that and this is kind of a cool trick that I discovered recently by looking at a project Polymer team did called shop which you can find over at shop Dot polymer dash project Dot org and if you go to the site You'll notice that when we first boot up the page it kind of does this like fade-in effect on this image You see like a low res version right and then just kind of fades in and what the polymer team is actually doing Is they're taking the original image and then they're downsizing it to 1% so you get something That's like 200 bytes and then in CSS scaling that back up to the full size of the image and then we're Loading the higher res version and we just crossfade them when the higher res version loads in so this gives sort of a perceived Performance improvement the user can access our content a lot faster, but they're not waiting around on a super big image So we can do that with our site What I'm gonna do is Over in finder I will find the blog that I've been working on here blog vlog okay images and I've already gone ahead and and down sample these images, but I'll walk you through the process of doing it So we'll take this photo of a lion that we've got so we've got Photoshop here We'll drop in this image of a lion now. This is a really high res image It's like 900 by 512 so so pretty beefy and I'm gonna go to the image Panel property whatever this thing is called and set image size 2% and we'll set it to 1% so that brings it down to 9 by 5 pixels And if we super zoom in you can see this thing It's just like just a bunch of random squares now, but it roughly approximates our final image and then we can export that for web and I usually use like a like a medium quality setting and I'm just gonna give it a different name So I'll call it like a picture one low res or something Now the next thing I'm gonna do is take that low res image and base 64 and code it into a string So that way I can load that string Along with all of the text content for my article now There's a number of ways that you can base 64 encode an image you can do it from the command line I believe with the base 64 command in Unix or there's there's a bunch of websites out there where you just look Up base 64 image and you can upload an image and it'll give you back a big string of text And that's that's one technique that I used in this case because I'm lazy So I've already gone ahead I base 64 encoded all these images. I have all the strings for them And I'll go over to the data that I'm loading in my application Open up the list page and along with the title and the slug and the image and the alt tag and everything I've got this image placeholder value now and inside of there I just have this humongous base 64 encoded string. Well, it's not that humongous It's like 200 300 bytes or something which is really actually quite tiny and this is what I'm going to actually load into my application Now I can't just use a regular image tag to load this thing I need to use a special element and the Polymer team has just such an element So if I go to the Polymer catalog, let's see Polymer Iron image is the name So we can check this out on the Polymer element catalog. This thing is awesome And what it'll let us do is load a placeholder while it waits on the higher-res version to come down So I'm going to just grab. Let's see. There's a snippet of code here that I want. Here we go So I'm going to grab the snippet of code And I can go back to my list page and find this image tag that I was using previously I'm just gonna replace it with an iron image. So let's see So we'll set width to 900 pixels Height 512 you can also do this in CSS if you if you wanted to have like media query breakpoints to change the size of the image I'm working quick and dirty here. So I'll just do it in line For the placeholder Right, if you if you go back and you look at our data, we called that value image placeholder So I'll grab that we can use that in our binding right so Image or item because we're in a DOM repeat item image placeholder Size and cover. Yep, that looks good. I totally want to do that Preload there's a fade effect that iron image gives us if we go and look at their docs This is kind of a nice thing. So there's a fade attribute we can set on this guy. So I'll say a preload fade The source is going to be Item dot image and then we can add an alt attribute to which is important for accessibility So we'll say alt equals. I believe it is item dot image underscore alt Okay, so this is going to go out It's going to quickly display a placeholder and then fetch the higher res version and fade that up when it is loaded I'm also going to add the same chunk of code over to our What is it our post page? So our post page we got an image here right Place that with iron images and here we called it post content. So I just need to update You know wherever it says item post content Hide that old image Okay Give it a shot. So I've turned off throttling I'm going to refresh the page and you'll actually even see even though we're on a fast connection We'll actually see some of that crossfade happening because it's able to load that placeholder super super super fast because it's so tiny But this makes a huge difference if you're on a slower connection So again, we'll go to the network. Let's turn throttling on now so We'll set it to like Regular 3g. Okay, and now let's switch to a different page. So we'll go from art to film Okay, cool. So we didn't see any stale images and We we were able to get that kind of nice fade-in effect while we were waiting on these other images to load I mean if we go to a really slow connection like gprs here What you'll see is as I go and maybe click on one of these posts We see the spinner for just a second Then we see the page content though and then that image fades up and this is really really nice Let's actually do like a super hard refresh to clear our cache so you can really see this in action Okay, so let's say I hit this page for the very first time. I'm gonna switch it to gprs so now I'm like super super super slow phone and switch to the film section and My text loads in super quick, right and these images They're kind of like rolling in along after it But I don't have to wait for those images to be able to actually start reading the page and interacting with the page content So the final product is just super super nice and it's very very responsive and very friendly to folks who might be on Slower cell connections. Okay, so that about covers it for today We've built an amazing site that is super quick on mobile using some of the fancier new app routing and iron image trickery that the Polymer team has given us now if you haven't done so please go check out some of the talks that the Polymer team recorded at IO these are all up and available on the Chrome developers YouTube channel and if you have any questions for me You can leave them in the comments down below or you can always hit me up on a Social network of your choosing at hashtag as Polymer as always. Thank you so much for watching and I'll see you next time So Matt, what's the one feature that keeps you coming back to native apps? Probably offline support. It's it's that whole thing of you know, you're gonna be somewhere with flaky network And you just want it to work. Yeah, that's probably it So offline is probably the one thing that keeps me going back to native apps as well Now like there's a bunch of apps that I need offline support in like news readers and things like that But there's probably I don't know kids today use a ton of apps that I don't like dating apps back in my day You have to run through the city with like a megaphone screaming. Why does no one want me? I'm probably doing it wrong. I'm just gonna say probably So offline User goes to your web page. They probably are gonna run into a situation where they have a flaky network Maybe they're on the train. Maybe they're you know at a conference or in a hotel, right? Now in the past we've had capabilities like app cache, which weren't really that reliable and sort of a nightmare Yeah, no one really used it and there's that classic Jake Plug post cash is a douche bag. Yeah. Yeah, these days. We're in a slightly better position We've got new API's like service worker now service worker is like a script that's run by your browser in the background And it opens up like the door to lots of new capabilities. Yeah, so there's there's push there's offline support There's background sync. There's like a whole host of other features coming down the pipeline Yeah, but it's like this really nice low-level API that lets you intercept network requests and just take control of what's going on with Caching. Yeah, so you've got your web page service worker in the middle before it gets to the network So we can kind of manipulate and basically outgoing traffic or just keep stuff from going to the network and just return Like a cache. So the first step to getting your app working with service worker is to register a service worker script That allows sort of background functionality Without the web page necessarily having to be open. Yep You're just making the browser aware that this is my special service worker JavaScript file How about we take a look at some code? So the first thing you're always going to want to do is just check where the service work is actually supported So if service worker navigator assuming it is you then just call navigator service worker register And you're passing the path of your service worker file and here we're just using promises So then in catch to just see whether it worked or not and that's literally it and The kind of the important thing to point out here is it's an it's a progressive enhancement, right? So if you're in a browser doesn't support service worker that never gets called You're just exactly the same land as you would have been without service worker. So you get you a same Non offline experience without service worker. What about what's inside the service worker script? So the minute that kicks off What the browser do is it would just go and grab a service worker file and then just start running it in the background of the page So in this case the first thing you're going to want to do is manage the install event So in this case self add event listener, so you're just saying in this service worker had this event And you want to open up a cache so caches to open you give it some name That's kind of important because over time you're going to add a different version Yep, and Once you've got your cash object you just call cash at all This is a super helpful little method because you literally pass in an array of Paths and everything inside that array. It would just go and fetch from the network and cash So here you're interacting with the cash API. Yes, so that's different from the HP cash This is a cash that you control so nothing will get deleted or replaced or added to it unless you explicitly do it But yeah So the only real caveat to all of this is in the cash at all if you add in like some random file that your server like errors out on And returns an error code that will make the install event fail the install event fails That means a service worker won't install which means the web page will never use it It's kind of just a safety mechanism if something bad happens in the install event service worker Just won't affect your page whatsoever. It will retry, but it won't actually affect the page So that's the install event That won't actually give you offline sport because it's not actually getting used nothing saying use this use the cash To respond to a network. That's why you've got the fetch event Tada fetch is using the new fetch API right in this example. We are but it's slightly unfortunate The fact there's the fetch event and then there's the fetch API because of obviously the name is exactly the same They are slightly different So the fetch event will fire and basically this will happen whenever a page that's controlled by a service worker Makes a request so for the page itself images styles anything It will run through this event and here what we're saying is caches dot match This is a super helpful little method that just says for this request Is there anything in the cache that can actually do like respond with it? So here in the following thing we say if there is a response then just return it Otherwise return the fetch so here that's where the actual fetch API comes in and this is basic same as an XHR So it'll go off to the network find it and return it and then that'll pump it up to the browser Those two steps alone will then just give you offline support if you cash everything Once you've got all this set up and you want to test that your service worker set up is working correctly You got to dive into DevTools. Yep. So serve up your app check that it works Go to network throttling and just toggle offline Don't if you refresh your page and yes, we can do the annoying air horner noise That doesn't just work like on desktop right that should still work on bones as well. So It's the best thing ever but yeah, so now you know it works offline, which is super awesome and This is kind of super high level There is a much better place to get all of this information in terms of like stepping through service worker It also covers some of the caveats as well as the activate step, which we haven't covered Yeah, if you want to learn more check out the service worker offline codelab over on web fundamentals For too long users have been left staring at a white screen For too long, they've been let down by the cruel seas of network connectivity And for too long we've been powerless to help We've been left Waiting but no longer a new browser feature has arrived a total game changer A feature that lets you control the network Network control you who is this new feature? Promises does it bring introducing the service worker So my friend son does this really cute thing where they install games on their phone and then for weeks after they keep getting Notifications saying that their village is under attack Can you do that on the web now you can now you can how? Basically, what happens is you register your service worker You then ask it to subscribe these to push message shows a little dialogue saying do you want to allow this to happen? Yes, or no, so hopefully then the kids won't actually enable this at that point But if they do then that point you'll get a special token is for that user send that to your server Keep it when you want to trigger a push notification You can then use that endpoint send it a specific request and that will basically wake up the service worker on that user's device And go cool. There's a push message. What do you want to do about it at that point? You can just show a notification you can go back to the server and say hey, what was this for? You show your notification, and then you can respond to click events nice So that's literally like the whole end to end flow start to finish So can push notifications can with the push API can they show me like images? Can I include content in there? What can I do title? Title text you can do body text you can have an image to the side of the notification and You can also do buttons now as well So you can actually add like two buttons that you can so I can show an image saying that my you know Showing that my village is on fire, but also a button to like extinguish the fire or watch it burn Watch it burn. I don't know what you're into It's also interesting because now we're looking at doing native notifications for Mac which is really nice because it means that we get rid of our own notification like center thing We're now going back into like native notifications and their trades on whatever else goes with it Push notifications are not a Chrome only thing right no So they're in Chrome and Firefox at the moment I think other browser vendors once they start doing service worker. They can start looking at it as well sweet There is some bad stuff we have Chrome and says we have to we use GCM. So we have some proprietary bits What's this GCM GCM good point Google cloud messaging? Okay, I've been drinking the Kool-Aid for too long So there's some proprietary bits you have to do for that But again, there's new specs that are coming up that will wipe all of that out So then because the moment you have to go into Google developer console You have to register for an API key. Yeah, all of that's going to go away So you just have one API one set way of doing this that all the browser vendors can then take and use It's gonna be so much better if I'm correct We have a code lab on push notifications as well. Yes, people can check out which is well worth doing because that one is Regularly kept up to date. I think my old blog post at this point. It's probably seen better days So basically you're saying don't visit your blog under any circumstances Oh, let's just blanket rule for all of my content. But yes, that's what I'm saying But yeah, there is a blog post and it will step you through all the guides and it also goes through GCM And how to set all that stuff up So yeah, go check that out. Oh and If someone wants to like Simulate push notifications dev tools, let's you do this. I think does it. Yes, it does. Mmm. Oh, is that the bell icon? That's the bell icon. Yes, and you can do that from service working towards cool Welcome to this supercharged now normally when we do our videos We get lots of comments. We get lots of questions on Twitter You know loads of things that kind of come into us and so we thought why not let's actually take us back and answer some of those questions How are SVGs rendered? They seem quite slow. Are they GPU accelerated? If so in what ways? I Have actually no idea cool. I did so They're actually DOM elements they But the SVG but every child is a actual don't all the like rectangle, right? So you've got to be careful because if you move them around they're going to trigger layout But the layout operation will stop at the SVG route It's one of the times we actually have what we call a layout boundary where the layout actually is not document scoped It's gonna be scoped to the SVG element. Don't you look at that? Yeah, the other thing is a transform normally We like try you know promote this thing to its own layer and then transform it around that doesn't work in SVG context in Chrome I'm not sure about other browsers But in Chrome we don't promote anything to its own layer when you actually add like will change or translate So it's always a repaint. It's always a repaint So you got to be cautious with that to be I actually expected that for an SVG because I think for some reason I think of it more than canvas like than anything else, right, right, but hopefully Hopefully some point that you know optimization might land don't know though And then are the GPU accelerated they can be if you've got GPU rasterization switched on in fact one of the best ways to improve SVG performance today on mobile is to make sure that you've got GPU rasterization for at least for Chrome and the way to get that if you just Google for I think it is actually Magic viewport chromium possibly or I think as Ganesh or GPU rasterization Chrome What one of those will get you into the world that you need to be in next question is it possible to? Disable I don't know why they put Anyway, is it possible to disable web animations on very very very very very slow devices It has to be at least five and they put three tortoise emojis afterwards I think I know what that person is going for slow going fully slow devices I I can't think of a way to Adapt your animations really I think what you could you post potentially the Performance observer that is in the works at the very least right now Could eventually help you do this my first intuition when I read this question was that maybe you can kind of abuse Request idle callback because that will only be called if your web page is not too busy And if that is being called you could use it to enable you have animations go the other way around having disabled by default and Basically enhance your web page with the animations provided. This is not under too much of a load Yeah, the problem I had with that is that You're now main thread Can so if you're animating in JavaScript, right all your animations are coming from the main thread Which is fine So you can then test for main thread availability with request idle callback or request animation frame or both but if you've got something that's like a CSS animation that is done with say a transition and you're just using the compositor thread And it's just going to keep going even if the main thread is janked up Then you can't use that technique because it's going to be like well I can't do any animations right now and the problem I have is that even with the frame timing API It's still only main thread availability So it's kind of gonna benefit anybody who's animating JavaScript, but it's not going to benefit anybody who's animating just purely with say CSS or something like that Overall though, I the thing I wanted to kind of ask myself was is it the right decision to? Disable the animations in the first place right cuz I was like if your UX can stand not having the animation It feels like you don't need the animation right animation is just shouldn't be for the sake of Usually they serve a point and if it don't serve a point then you might as well skip them because it's about being a little bit Mindful about the user's resources right right so I was like But I get it's a sliding scale and somebody might be like hey It's an added bonus if your device can take it or whatever As I say, I don't I don't think you can do it reliably today And I don't know of anything that's like in the works It's just like this is the cast iron way of saying this device should be good to go But I think you're right request out of callback probably the closest we're gonna get well There you go. So those are the questions that you asked and We would invite you to ask more questions in the comments below Twitter. I'm at aro twist at the summer That's like that's like the summer but in German, which I learned I'd forgotten all my German until I taught him So ask your questions ping us on Twitter and we will catch you next time So Matt I'm working on a new web app for lonely people Okay, what does it do? What's it called? It's called words with cats now Words with cats. It's a brilliant, brilliant name. Um now I want to show an icon on my phone's home screen someone launches this and I also want to be able to show like an Icon or some visual in a splash screen of a cat reading a dictionary or something a cat reading it Do you or you were thought leader? How can I get that done? So that's the set crime now has the at-to-home screen stuff So basically if you meet a certain set of criteria When a user is basically engaged into your web app it will come up a little banner saying hey We'd like to add this time screen. So you basically to be on a hps You need to have a service worker and you need a web app manifest And then after that it's basically depending on the user coming back a couple of times then it will show the banner So the web app manifest is the main thing that you need To enable all of this along with the other bits But the manifest is just a JSON file at that point cool So it's just a JSON file. Is this a crime on anything? No, no, this is all the standard space So basically any browser can look for this link rail tag that links your manifest JSON file at that point They can pass it and it's just going to be you have to have certain things to find for then browsers to take it all out Right. So the manifest lets me customize my icons. What other what other stuff can I configure in there? Oh You can define short name which will be the text underneath your icon that you'd normally see Theme color which Chrome uses is like the URL color along the URL bar background color is for the splash screen So if you have that at home screen, they click on it It'll launch and basically while Chrome's loading what you can do is show a splash screen That's like solid color and then have an icon on top of it along with the text So background color does that you've got an array of icons So again depending on what the browser wants to use the icon for it will just pick the best size for it Start URL is super awesome What that is is basically you remember back in the day we used to have our time screening Chrome where it's like hidden in the menu Yeah, so what that would always do is whatever page you are on that is where you will get pointed to when you click on the icon From the home screen start URL lets you define where that is now So if you're if someone was in the middle of a blog article click on our time screen now You can say actually just go to the home of the blog Then you've got display display is basically Rather than launching browser mode you can sit there and say actually I wanted to go full screen So you can look launch it full screen the same way that a native app might look like right? Yeah, exactly But alongside of that there's also in the spec orientation. So you could theoretically lock it to portrait or landscape cool So for games, that's particularly. Yeah, like you want to do like force to just like thumbsticks And yeah, the nice thing especially I was gonna say with the start URL You can actually then add the query parameter So then you can like track how many people are using it So like home screen equals true and then analytics will just show you sure so that's pretty much the bulk of it Nice is there if I wanted to like validate that I've got a legit manifest Is there a tool I can use for that? Yes, someone has built a web app manifest validator I think DevTools we're also going to do is you could like force a download of the manifest and get DevTools to pass it I believe we mentioned as much in totally tooling tiers But I haven't actually used it myself Admittedly if you don't use something like that, it's kind of hard to figure out whether it's working or not Yeah, so those are all we're checking out. Okay, so we talked about the web app manifest the manifest validator It's we're checking out DevTools is looking at it Are there docs on this available as well? The best thing to look at is Pookeland's blog post It covers example manifest how to add it to the HTML page and then how to debug it as well So that's probably the best bet sweet and plus it's in web starter kit and a whole other host of the projects that we do How are we doing? Are we all good? Hello long hi Long to the the fireside chat about progressive web apps I'm Paul and This is the panel that we have here. So what I'm going to do first Is it introduce them and then I'll just explain what it is we're going to do So we've got Dion Almeyer right here who's engineering director from web DevRel To his left Jake Archibald developer advocate I could be so much ruder, but Oh, it's taking so much effort immediately to his left Dmitriy Glaskov who's a software engineer on Chrome and then it's Alex Komorowski Who is group product manager on Chrome? Who's next there? Owen Campbell more to his left there. We are yeah product manager Adrian Portafelt who's a software engineer on Chrome and then last but not least Alex Russell Also a software engineer on Chrome now. So we're talking progressive web apps and if you've got any questions during this There are microphones to either side Please do use them Please come up and ask your questions But do use the microphones because it means that they get it for the recording. So that'd be great but we also put out questions on to Twitter and slack and so forth and We're going to probably start with some of those Also on the screen you can see URLs for pinging at Chromium Dev and The slack and so on so you can also ask questions during this that way and they'll make their way to me via the power of Google Docs. Okay, so the first question and that we got through which is going to go to Jake. I think How should I build a progressive web app when Safari doesn't support service workers? You should use progressive enhancement. Is that the correct answer? Yes, okay, you're looking at me like I'm somehow responsible for the question.  No, the crowd But once bit late so When you start enhancing with service worker and things start loading faster in the browsers that do support service worker Like which is at the moment firefox and chrome and opera Then that becomes good evidence for the browsers that don't support service worker to just start implementing it or to make their implementation faster What I'm saying is you're you know you have to control here over the future of the extensible web But there is a sense in which a lot of the things that people look to from a progressive web app They do rely on a service worker, right? I mean this is what people are it kind of feels like that, right? Well, we've survived for a long time without service workers and the web was still usable So it being able to add these features into to get more more engagement. I think that's that's yeah, it's a great thing I think to the progressive enhancement is so important that we made it part of the name So that just gives an like an emphasis on how much we think that's central to the idea In fact, we just published a case of a yesterday AliExpress which is a company that as an e-commerce company they built a progressive web app and in doing so They also invested in proving their mobile website and they actually saw a lift of I think 82% in the conversions They saw on mobile Safari as well So the idea is that by invest investing in your mobile website is always a good idea It just so happens that in browser and support service workers that experience will be super charged So I think it's really quite compatible actually and we saw this already with things like the Facebook website Like they their website has been there for years And then they've added service worker in as an enhancement And now you get the push notifications and then hopefully soon some kind of offline first experience and now they're seeing more usage You know usage grow because of that. I mean, I don't know the figures that but I know it's definitely from one user I use the website rather than the native app now because of that because it does everything I needed to do All right, let's move it on. Oh, this is a good one. How do progressive web apps work with amp? That'll be I guess Alex Russell Without which with with them amp. Oh so For those who haven't seen the sessions amp is a web component dialect for making very very fast loading Pages usually articles content articles, but amp has a validator, which means that you can't run your own scripts You can only run amp script, which is how amp Continues to stay fast. That's why amp files generally work so well Is that the validator keeps you from running your own or third-party scripts? So this seems incompatible with service workers which require you to register a service worker The good news is that the amp team has built an amp install service worker element and that element is something that you can use on your amp pages So from there once you have the service worker installed and running on your site You can intercept navigations like you normally would to serve up an app shell and that can be an amp viewer So you can keep the same content while upgrading from a relatively bare bones But super lightweight amp experience on first load to getting that richer more immersive more engaging Second third fourth Experience out of the gates very quickly once the service workers there and again It does the progressive enhancement thing because you start with a totally valid completely workable amp document Which is a great way to read content So amp is a starting point adding service workers and then layering in your app shell later for a custom behavior for Richard Stuff once you know that you've got that cached in the service worker And you don't have to wait on the network to get that more immersive behavior. I think is this golden path I think that's a great way to go and that you've got to talk about this tomorrow, right? I've got to talk that outlines what the Washington Post did tomorrow And we'll be talking about this extra sort of additional Opportunity at the end. Yeah, do you guys see the Washington Post progressive web app with amp demo those today? Yeah, so I think that really shows off the experience and you know Alex You talk about how progressive web apps are just you know web experiences that take their vitamins I feel like amp is like the prescription medicine where it's like hey you guys you've screwed up for too long Here's a quick pill that will help you, but you may want to change your lifestyle and take some vitamins a little bit of exercise A little bit of healthy eating. Yeah Just interesting thing that Washington Post is just the beginning or experimenting of how this stuff fits together, right? I mean there is more and probably more interesting integrations that you can think of Just to follow on because there is a following question Again, I guess it go to Alex, but is there a development strategy which allows you to have that? One code base that will service both the progressive web app and amp content And if you know do you know can you reuse code and so forth? Yeah I think what I just outlined basically is that strategy where you catch your navigations in the service worker and serve up an app Shell which has that more advanced more customized Slicker behavior only for the users who can support it once you know that it's going to be cheap or free Right only when it's cashed locally inside the service workers caches And you don't have to go to the network for it, but all those URLs should load nakedly as regular amp documents And you can move an entire site to amp today Have it on your origin have it proxied out to the CDNs have it validate and that all works. Thanks to the amp service worker element All right, let's move on Question it sounds deceptively simple When does my website start becoming a progressive web app and the context here is let's say I just add push messaging Have I got a progressive web app now? Who would like to take that one? For me and you can feel free to correct me It's when Chrome will start offering Users to add it to their home screen. So it's a set of requirements there, which is HTTPS It's having a service worker. I think at the moment. It's just having a service worker But we're going to tighten that to offering some kind of offline capable experience and having a manifest So all the icons are in there and its display standalone So so the user can add it to the home screen and it will look like a native app And this is why we require an offline capable experience because we we want users to when they when they have a home screen icon And they tap it and it loads with it in Chrome They we want it to feel native for them and if the browser has to show a default Connection error message then that's that breaks the the native contract I Wait, I think of wait I think of a progressive web apps is actually as a more general concept that you want to reach towards just like Ajax It was like a back in on desktop web. It wasn't like one of my Ajax like what does that mean? I mean there you can always be doing more I'm trying a better experience That's more in line with that sort of that golden ideal Yeah, and I think when Jake mentioned chrome there that doesn't mean only when chrome does it Of course lots of the browsers are supporting all of these features. Yeah, so On a technical level chrome implements those specific heuristics other browsers may implement different heuristics And you might imagine getting progressive web apps different ways, right? The fact that we have this one prompt that triggers at this one moment Which from a user perspective can feel a little bit arbitrary is basically an implementation detail all the technology is very open It doesn't demand that browsers create any specific UI so I expect to see a lot of evolution actually and how browsers present the ability and willingness to keep these things to the local system and how you run them I expect that to sort of change a lot You can imagine listing these things in stores or having Persistent UIs that tell you that hey this thing is a progressive web app as opposed to that Occasional prompt those are all possible futures that other browsers can explore in fact that we're also exploring different Treatments for it and seeing other ways to improve the treatment we've got today But I also want to correct one thing though I think a lot of people I think a progressive web app says it doesn't count until it's on your home screen and To me that isn't the be all end all that it is with for example a native app where it's the same thing And I think that users can get value out of it from push notifications or just from it loading more quickly when you come back to it And so the fact of the matter is Not everyone's going to want want to add your thing to their home screen And that's fine because you can still create a really meaningful experience and add value for them And as you do so maybe over time they'll say you know what you are pretty cool Maybe I will add it to my home screen a decoupling these was was sort of this thing where we had to give it a name at Some point because they added up to an experience but the goal was an experience for the user and not a particular bundle of things You had to have all at once like the native app Model of having to go through a particular Huge transition a big step phase Big phase change a big step to get to the moment where you can do all this stuff because you said yes to it all at Once that's pretty tough from a user experience perspective And so we want to make them more a la carte and the fact that they add up to that ability that moment Where you can get out of the home screen or that moment where you can Ask for push notifications. That's just the strength of the web being more a la carte What you're talking about before like being able to have some kind of Store or place to find these I think that's really interesting. I think that's there's something I would like to see Google take on this to Create some kind of engine for searching content on the web Somehow users can find these that sounds really hard. It feels like a space. We should get into So Jake since you started talking again There is a phone because you mentioned the fact that offline is a thing and actually Alex you kind of mentioned that it's about the Experience not necessarily checking all the boxes. Why is it then that apcash isn't valid as part of the requirements list for a progressive web app so I've had a lot of questions from internal teams in the last couple of months about why isn't apcash good enough And so I wrote a document Which I haven't shared publicly for obvious reasons called apcash in your architecture not even once and The tldr of this document was basically you start with the best of intentions and Apcash's design decisions cause you at every moment to contort yourself ever further away from the experience you wanted to deliver and before you know it You've centralized on a single URL and you've decided that you're going to do hash Navigations and not push state and that you're going to do offline only and not reliable performance that you're going to give up on a bunch Of the experience differences that you're really trying to effect To get to something that apcash will allow you to do and so I think it's worth sort of Understanding where the endpoint of that journey is and then deciding that that's not something we should buy into It isn't that apcash is bad technology It's just that it's not designed to build reliable performance It's designed to give you special case offline and special case offline kind of isn't worth having because Offline is a very much a special case. You're only in an offline mode very occasionally when you set your phone into An offline state or when a navigation it finally fails But you're on a flaky connection basically all the time and so handling the flaky connection and getting reliable performance is the goal That's the user experience win and confusing the two Doesn't really work doesn't help anybody Plus we keep finding horrible security things in the apcash spec. Oh, yeah, we're taking it off of HTTP by the way Yeah, you just yes Kind of terrified. Okay. Let's move on one thing Okay, a lot of people spend a lot of time trying to make apcash work and went through all of this pain Jake for instance yes this guy But lots of other people and so we did release just the beginning of a library Today or yesterday that tries to kind of say, you know, if you've done all of this work to generate these manifests and all that like That's a lot of work So here's a path to make that work with service workers and then again, hopefully you then kind of move off Over time. So if you do have apcash working now, we're trying to make that pain go away a little bit And it doesn't have the security bugs that apcash does so safe to use Okay, the next question is a Security related when I suppose will we ever get signed or trusted progressive works with the same security properties and the privileged api's of Chrome apps, I guess Adrian do you want to take that one? Yeah, that's actually a very interesting question. I've heard a lot of developers asking when will we get specific api's that I really like from the chrome house platform and the answer is that We want to keep the web open so that you click on any link and You as a user don't have to be afraid of what's going to happen when you click on that link And so for that reason we're taking a very reasoned and measured approach when we look at the different api's that can be adopted by the web I don't think that Signing and packaging are necessarily the the distinction here rather It's the discovery mechanism is that you're getting to a website just by clicking on a link You don't necessarily know where you're going and we wanted to just begin working immediately. So our approach has been Runtime permissions for the web where we try to first of all design the api's to be safe by default and then have permissions where users can opt into experiences that might potentially have Some amount of security risk although again our first aim is to do through designing the api's that there are no major security Risks with any api's and this takes time and we have to think very carefully about which api's we release So, you know in the long run I'd like for for most api's many of the cool things that you could do in Chrome apps to be available to the web But it's not going to happen overnight because we have to make sure that the security experience for for each one is done correctly I think it's a really important broader point to The web strength is it's low friction the ability to just tap that link and get to another experience And that's one of the things that enables so many really cool business models and so many interesting diverse things on the web And it's not like we all woke up one day and said you know what it would be great if by tapping on a link We could load it immediately without an interstitial. That's part of the design from the very beginning. It's been very meticulously managed and Evolved and strengthened over the past 20 years. It's something that's fundamental To why the web is so successful Okay, we've don't forget you can come up to the microphones and ask your questions if you've got them But there's a an interesting one that's coming on the Twitter's Android instant apps brackets no need to install Versus progresses web apps how slash where do you see each being used cage match? wrong one fight In all seriousness, so of course at Google. I think we're a large company We always want to make sure that developers are successful on whatever platforms they choose The way that I think about it is the web has historically had this really low friction, which I conveniently just talked about That's very important to this awesome diverse ecosystem, but it's also had low capabilities And if you look at native apps, those have historically had very high capabilities But also very high friction in part due to those capabilities. So progressive web apps has been a multi-year effort Working with standards working with other browser vendors to design these APIs very carefully to maintain and allow us to Responsibly bring these capabilities to the web and I think that instant apps is the same kind of multi-year journey To bring the lower friction to native apps as well So I think the that really cool demo that I think we all saw on the keynote is something That's like an aspirational goal to get to I think will be a really cool place now one of the reasons I love progressive web apps is because it's just web technology. We've been using this stuff for many many years It's been evolving over all the time and you can deploy these things today In fact, we published seven additional case studies from businesses around the world Indonesia, India, Africa Many other places just yesterday showing businesses having really really really strong business metrics by adopting these technologies And that to me is one thing that's so cool about it. It's cross browser It's cross cross platform even because we've seen lift and conversion rate on iOS people who invest in web That's good because Everybody else got an intro and then they were like you're just walking on your Sort yourself out. So I was prepared to be like ladies and gentlemen, please welcome to the stage Paul Lewis But I don't need to do that because you're all cheered. So thanks for that But while I was waiting, I don't know, you know and somebody mentioned something and you can't Unnotice it. I'd like to thank Jake for pointing out the music Before each of the sessions although I noticed that it has this kind of coral kind of Thing going on which I felt added a certain amount of like gravitas and sort of epic to the proceedings And now it's like what's more epic? the new I elements So good anyway, that is exactly what I'm going to talk about now So far we've had summer and we've had Jake talk about performance and streaming and stuff And I wanted to talk about the bit that happens after that the bit where you have your UI elements And before I get into it. I kind of wanted to put that into a little bit of context When we talked about performance historically on our team last year year and a half We've talked about a thing called rail and rail stands for response animation idol and load and it's a way of thinking about performance that puts the user in the middle and Let's us figure out what they expect from things. So for example If you tap on a screen you expect something to be coming back on screen in under a tenth of a second if you scroll Or there's a transition. That's an animation and we want that at 60 frames a second Idol is a bit of a funny one But the general idea is that you should do work when the user isn't interacting and and when there's opportunity to do so when the Main thread has some time and we do those in 50 millisecond chunks so we can keep responding to users and Loading we want to keep the user on their train of thought And so you've got about a second to get something up on screen whether that's from a cache or the network Now when we talk about rail, this is the kind of world view that I think many of us have today We kind of go yeah responses. Okay. Yeah, we don't want it to be laggy. That's fair enough It's kind of important scrolling animation. I definitely heard that's a thing and that's something I want to make sure is good Idol Yeah Sure Seems good Load load. Yes whoo back in the safe. Okay load. Yeah, I'm gonna find concatenate all that good stuff But here's the thing This is kind of where we're thinking of being on people's home screens and a closer look at that home screen Raise is an interesting question. Which of these is the progressive web app? Which of these is the native web app? The truth is users don't care What they care about is that the thing that they tap on works really well and They would never say something. Oh, wow. It skipped things. There you go back would go Rewind, okay Nobody's ever gonna say this and if they did it was on like this that up looks like native I hope it behaves like it. There you go. They expect it to behave like a native out They expect your stuff to run. Well, I want to say behaves. There we go. Hello Behaves for me is like performance and it's about does it behave as we expect does it do the things that you know I interrupted it to do the right things right Since that's the case. I think we can reevaluate rail to look more like back Bad clicker More like this The response part of rail Well, we expect our responses to be Instant like every time instant. So that's just now more important animations Yep, they're down there and There we go. They're going up there Because we expect again we expect instant transitions. We expect, you know scrolling to be super smooth idle Well now if we're doing more Work to make responses and animations good idle is something we're gonna have to be more tactical about We're gonna have to do some work when the user isn't and we have things like request idle callback for that So idle just went up They're all going up Good news though. I think if you're expecting somebody to add you to home screen and run your stuff lots of times Hopefully you're gonna have a service worker. Hopefully you're gonna be running from a cache and therefore I think load Drops down to here Don't think it's unimportant. Don't get me wrong You still got to do a good job to get that first load there, but I think over time I think that's what we're talking about. So if you're being home screen minded I think it looks more like this and I think if you think about the the native apps that you run You have a similar expectation. You don't ever sort of sit there thinking about well this APK took a long time You know when you're using it for the 50th time you're thinking more about how this actually behaves whether it's got the features You want and so on So with that in mind, I wanted to talk about three Individual components, but they give me an excuse to talk about about a bunch of other things and I can explain I suppose the way I categorize my components from deterministic We know upfront we can hard code the values for those animations and interactions through something. That's a little bit less Known upfront all the way through to something where we've got no idea about how it's going to behave Until somebody actually clicks on the thing or we have a little bit of an idea, but not much So those three components are a side nav Some swipable cards and an expand and collapse view Let's jump straight into the side navigation Which I think most of us have seen before seen these yeah, we've seen these quite a lot So what I'll do for each one of these and I'll explain the theory of how I would approach them to maintain Performance and to kind of be performance minded I will be leaving probably some glaring omissions in the area of accessibility But just as well Bob Dodd's coming on next and he's going to talk about accessibility. Oh, it all fits together wonderfully Anyway, the theory for the side nav what we're going to do is we're going to pop on a Containing element over the top of all our content Into which we can place a semi-transparent black background to obscure our content and then we're going to have this Contents bit with our actual side nav in it, which will slide in from the side like so So the CSS for something like that For that containing element is going to be position fixed left zero top zero Width and height 100% some people like to do right zero bottom zero That's fine Works just as well Overflow hidden because we don't want any scroll bars But the pointer events one is a bit of an interesting Sidestep that I want to take it lets me talk about something that's kind of like a primed element so these are elements where you Want that thing to be ready to go and a side nav is one of those because when a user taps on the button They expect the side nav to just come straight out Right, so the general idea behind a primed element for me is that it's something that could be activated at any time Okay, like a side nav. Yeah, it probably fits that bill and if you were to toggle its visibility It would take more than a hundred milliseconds as in because they're probably going to tap a button And you rail tells you you've got a hundred milliseconds to respond if you take longer than that It's going to feel laggy so these are my sort of two criteria as I say I'm leaving a glaring omission in as a regards Accessibility so hold on to your hats for that bit coming next But all the same we have a primed on I think this is a primed element I think it fits and as such we can take a couple of shortcuts One of which is we're going to promote the content bit to its own layer And if you're not familiar with layer promotion The idea is you want to separate out an element from the rest of the page so that when you paint it or move it around You don't affect any other elements on the page It's the same kind of deal is you know if you are not package or whatever and you create a layer and you can sort of Mess with the pixels in it and you don't mess with anything else Now the easiest way to do that today to create one of these layers called a compositor layer is to use will change transform So if you imagine The simplest possible page With a photo of bald idiot and a nice guy and You Put will change on to said image Now you can move it around with a transform And you can see that it's kind of separate from the page. Obviously. This isn't happening in real time But it's it's the idea of separating these things out now You may be sitting there thinking this seems like a great idea star will change transform Burn that from your mind Okay, if I'm not clear don't do it The reason you don't want to do it is to fold firstly You'll want to keep your memory usage down, especially on a mobile device if you create layers You're going to use memory. You're going to have management. You're going to have textures on the GPU all that kind of stuff So you want to do this as Needed now with the prime element I'm going to make the argument that you probably want to do something like the will change in your CSS But in other cases where it's not known until you start interacting you probably do the will change in your JavaScript The other reason is you want to keep your time in compositing to a minimum Compositing is where we take all those layers and we squish it back together and put the pixels up on screen now Of course, if you made lots of layers, that's a lot of depth sorting It's a lot of management and it's a lot of putting back together and that takes time So you want to be tactical about this So we've got our promoted layer and as you can see in the CSS I'm going to put will change transform on it like so and then come back then I'm going to transform the contents off to the left by a oddly specific 102% and if you're curious about that is because I've got a shadow and I just do an extra couple of percent to hide it Cheating but that's programming. You know, it's just cheating right sometimes and I'm a cheat when it comes to programming I'm very very not otherwise, especially not when playing little games with my kids I'm very fair never cheat Anyway, eventually the user is going to tap on a button and that's going to show the side now Which in this case is just going to add a class and that class is going to remove that minus 102% Fairly straightforward and we get something like this where it slides in from the side that semi transparent black background is the same kind of deal Here we're going to do a will change of opacity from an opacity value of zero to an opacity value of one and Getting rid of it like so is just going to be the same in reverse We're just going to remove that class everything goes back. It's great And we can just do that with this like hide side nav, which I put on the containing element So if you click anywhere, I'm going to hide the side nav Which is a bit bad if you actually click on something in the side now So the way to get around that is to just add an extra handler for that particular situation Which cancels the click, which is just a stop propagation So I'm kind of canceling the click and it works out really well. In fact, so well This is what it looks like in reality. This is one that summer and I built this is actually running on a nexus 5x And you can see you know slide out slide in I actually added a bit of drag thing to it, which you can see if you want to afterwards When you take a profile of this in the dev tools timeline, which is kind of what you want to be doing with all your UI elements I have the side of sliding in and sliding out, which doesn't look very big. So let's zoom in You see that green chunk is the frames per second and we're hitting a nice comfy 60 frames a second on a nexus 5x And below is the amount of work per frame, which is pretty low Because we're not doing much. We're just using transform changes If you're interested in seeing that actually being built for real There's the TLDW and there's also a live stream Which was about an hour long with me and surma where we built the side nav Bugs and everything it was great, but you can catch that if you if you haven't seen it. So let's move on since we've done the Since we've done the fully deterministic minus 102 percent to nothing we can move on to the swipeable cars Which is a little more interactive a little more dynamic So that's this one. You've seen it probably some that Google now, you know cars and it slides up to take its place the theory here is Again, we want to promote to a layer for the thing that's being interacted with But we want to do that on demand We don't want to do this one ahead of time because if you had a lot of cards That's a lot of layers and a lot of memory usage not a good idea We also want to use transform and opacity as well because we're going to transform this thing off the side And from a kind of behavioral point of view we want it to fade out because that gives the idea of being dismissed It's a kind of something the user would expect Now At this point I want to take a little bit of a detour and talk about kind of game loopy stuff Which is something that any game developer would be like yeah and It's extremely useful in the situation what we want to do in These kind of cases is decouple our input which can happen Fairly sporadically and whatever from the actual Rendering and drawing you bit which you'd expect from a game because your character stood there You don't want to you know you want the kind of game to keep moving Even when you're not moving character right same kind of thing We want this animation to keep going even when we're not actually doing touch events for example And the way we do that is we call request animation frame for every frame of the interaction And we'll give it our update function Which you know there's a nice side effect gives us a function that we can just call to be like just draw it Even when there's nothing else going on Now we've got a touch move at the start of the frame. Well, that's okay. We'll just use it We'll just store its value and we'll pick it up in the request animation frame if it comes in a little bit late Or it doesn't come in at all How big deal we'll just use the last known good value if by some weird weird chance We actually got two or more well again. We're not doing work per input event We're only going to do it once per frame, and we're just going to use the last known good value That's good So this is a model that you probably want to adopt if you haven't already for this kind of work now we get to the actually to adding the event listeners and and Fair enough. I'm going to share them between mouse and touch. I think Point events might help a little bit here, but you know, I've got this so touch start touch move touch and so on and as a side note the Adding of these touch handlers to the document is bad generally speaking and the reason it's bad is this really You have The compositor thread which gets the user touch It's the one that actually is told about the interaction first and by default it would do something like scrolling It would just move the page up and down but we registered a touch move and that involves the main thread and If the main thread was busy or our touch move just ran for a long time for some reason Then eventually it'll come back and the frame will be shipped but in between that Ta-ta-ta We've blocked the user Oops So that's not as good and there is a way around this. It's new as of I believe Chrome 51 and it's in opera and firefox It's in development according to chrome status Same with webkit, but this is encyclopedia large obviously And I'm not sure about Edge. I can check with the folks on that team. However, what we do is we add this passive true To the event list now one that says is I won't call prevent default I'm not going to do it So don't worry about waiting on me in order to do the thing you're going to do still give me the events and give me the Information, but I'm not going to prevent default. Okay, and the browser goes cool I won't block then I'll just get on with it. That's great So anyway back to where we were We have our event listeners and we talk about what they are going to do for example, we have this card It's in the start X position. So what we'll do is you've tapped on it We'll go to our on start which is going to basically Ask for the position which lie to be page X or the first touch events page X and then We'll add will change on it dynamically Which will give us a bit of a hit because we have to create the layer and everything, but it's probably going to be okay probably Now you actually move your finger across and we have to kind of go in what's the new position? Which is fairly straightforward. It's the same kind of deal We just track the page X or the first touch events page X and since we know where we were and where we are We can figure out what the translation should be such that in our update function We can say if you're dragging the card your translation is the current minus the start and what we will do is we will apply a Transform with that value great stuff That's gonna work. We're gonna be able to slide across we can change the opacity in the same in the same kind of way But we now need to think about the next part which is I'm kind of dismissing the card, right? Or I don't go far enough and it comes back to the middle. It's the kind of this is the behavioral bit So if we consider a normalized Distance, so it's at zero if it was out to the side We could say that was position one or back in the other way That's also position one what we can do is we can kind of throw up these thresholds Do I put them a 0.35 when I was doing this you could pick 0.36 or something else entirely. It's very exciting. What will I choose today? Who knows? That's web dev So I put 0.35 and If you don't go past 0.35, I'm gonna slide back to the middle if you do go past 0.35 I'm going to dismiss the card fair enough. Okay, so that's in the the on-end Like so there we are threshold card width times by 0.35 and it's this is this target X value Which we're going to come on to in a moment. It's defaulting to zero if You go past the threshold. We're going to choose either the card width or minus card width depending on which direction you were going okay, and we can pick that up in the The else here where we say translate X plus equals target X minus Translate X all over four and if you've been around for a while and Done this kind of work. You'll probably recognize this if you haven't Very exciting little one-liner that is incredibly helpful when you want to do what I call the easiest easing in the world or easy Easying takes always takes this form. Okay, it's value plus equals target minus value all over strength And I genuinely have made other developers like memorize that Because it's incredibly helpful. Let me show you what I mean kind of worked example Let's say you want to get this box from zero to a hundred and you're basically target minus value So that's a hundred minus zero all over strength, which is four one with it 25 pixels cool on the next iteration It's a hundred minus 25 which is 75 all over the strength Which is four that's 18.75 and as you build it up you're gonna see that it's gonna slow down It gives us a nice kind of slow down easing feel to this so that your box would go sound effects not included Okay, so that's this one line, but it's an incredibly helpful line It's either gonna ease us back to zero or it's gonna ease us to the car dismissal point now We need to detect doneness No, better word For what we're doing here. Is this animation done? Can I say that we're finished with this? Well, okay, the way we do that is well, it's either you go there and back to the middle Fair enough in which case we can just say are you nearly at the start If so, yeah, you're probably done That'll work that will get us most of the way there if you are just reset the target allow the user to interact again Other one is basically you slide you've done the slide out to the side like so And we also know that we're gonna fade out the card. So I mean this is pretty cheeky But we can just ask is the opacity really really low if it is it's nearly invisible if it's nearly invisible It's going it's going going gone and in fact gone so much that we're going to remove it from the dumb with remove child like so Now that will cause all the other cards to jump up immediately because the Dom You know we took out an element and saw the other ones went cool. There's some space. Let's take it Which we don't want we want them to animate we have this function that says as much as much and it looks like this You know that kind of slide up. There you go. That's the thing you want So what we do is in our animator the cards into position what we're going to do is we're just going to ask for the current card and We're going to step through all the remaining ones like so and we're just going to basically push them down straight down By a card's height so you go back down to where you were please just ignore the fact that we just removed a card Do you stay where you are and then what we're going to do is we're going to wait a frame for that to take hold Because styles will run after the end of our JavaScript Cool, and then what we'll do is a swish on a transition on transforms and we'll get rid of it And that'll cause all the cars to go and that'll look great Cool, and then when we're done We can reset the target And in reality, this is what it looks like This is another one that server and I built again. It took an hour. There were bugs weird See you go slide swipe. It's great If you go to timeline and you were to take a recording of that Again zoom in and it's actually in two parts this one The left hand bit is the car dismiss. What are you doing slides? Don't do that to me Maybe it's me and Jake maybe Maybe we just there's something bad going on. I'm blaming Jake. It was all fine Until Jake came on stage and everything broke for him Interesting coincidence, yes So the car dismiss all that's right there And then there's the other bit here which is sliding the cars and you see there's a little dip at the start And that's because that layer promotion of oh There's a bit of layer promotion, but the kind of setting up of those card animations did cost us a little bit So if you're interested in that and you want to see that one built. What are you doing? Seriously, okay, if you want to see that one built. There's a tldw There's an hour-long live stream that you can catch of that one as well Swipeable cards right we can move on seriously. I'm just going to stand around here. Okay The expanding collapse is the final one and it's the one that is the kind of fully dynamic one because You could pick any of those cards. They could be anywhere on screen and Okay, in this case in the mobile case they might do a full-screen takeover, but Um, they might not they might just expand a little bit or something like that And we don't really know ahead of time. We can't hard code those values And if we try it's going to be pretty horrible. So how do we handle this situation? Wel