 Good morning ladies and gentlemen the program will begin in five minutes Please take your seats now and silence all personal electronic devices. Thank you Hey, everyone, I actually don't know why you're clapping me. I'm the boring one today So welcome everyone. I'm actually on stage for a couple of minutes I'm here to talk about some of the logistics for today and tomorrow. It is a two-day event There was some confusion about kind of like what day two is We've got a whole bunch more talks on the second day So just to let you everyone know everyone's tickets are still valid for the second day, which is a good thing So anyone anyway, anyway, anyway, anyway, hello everyone welcome My name is Paul Kinlan for anyone who doesn't know me I work on the chrome and the web developer relations team at Google And it's actually really exciting to be here not only because like it's a great city And it's great to talk to you all you guys is that I get to bring the weather with me, right? I get Liverpool it was raining when I left and it's I'm sorry about that if it was me Yeah, I'm only here to do the logistics today to talk about kind of some of the things that happen in and the overall flow of the event We've got a whole bunch of great speakers today And I will say sorry to our captioners and everything because I speak really quickly as well So it's to the thing. I do want to highlight one other thing as well It is a free event and we do have security At this venue, but please do make sure that you keep all your belongings with you all time And you know where they are that would really help out So I'd also like to say hello and welcome to our live stream This was kind of organized really last minute and then the team behind this has done a whole bunch of really great things We have about 60. I know the numbers don't add up But we have about a 60 different live stream kind of viewing parties that are happening around the globe as well So we have some in Kuala Lumpur. We have some in Japan China There's a whole host of happening in Africa. I'm really amazed if anyone I can't even see the screen If anyone's up at America this time, but you know, maybe that'll happen and that's pretty good But we have like a wider global audience around this which is really really good. It's really nice to see So one of the things I want to say and highlight and this is a really important thing from our side is there is a code of conduct for this event We want everyone to have the best possible experience at this inaugural Maybe maybe the more progressive web app dev summit This is an inclusive community and no matter your experience or your background You're welcome here. We encourage you to be excellent to each other sounds very Bill and Ted that But you say hi to new faces people that you don't know build on one another's ideas And if you have any uncomfortable experiences, please report them to us. We have a number of staff around the venue They're either in the blue shirts the speakers Oh, we have an email address as well that you can kind of contact if you have anything any issues We do have a zero policy tolerance Tolerance policy for harassment of any kind and our full code of conduct is available on this site And you should I would encourage everyone to kind of read it if you haven't already done it There are a number of other posters and signs around the venue if you to be able to read and kind of see what's happening as well The other part as well is please do share any constructive or positive feedback that you have as well And like I said before the staff can be identified around the venue and we're here to help you have a great event So That's one thing the other bit as well. It's a very tightly packed agenda today It's it's talk after talk after talk and whilst we have breaks We don't have many and much time for question and answers So we have two or three different ways that you can contact us if you haven't already joined the chromium dev Slack channel we have our entire team available and ready to answer questions as they come through So if you have questions in any of the talks just feel free to drop something in either the speaker when they finish We'll answer the questions or the people from our team will also be able to answer them kind of there And then or if you want to use Twitter and maybe even promote the vet You don't have to but like if you want to talk to us around this Get in contact with us in the chromium dev team and our team again will be available I'm happy to help. We do have a code lab session. It's on the third Code lab area as well So you can go in there's power and there's a whole bunch of other stuff as well And we'll have to the our team members there to help you be able to kind of you build your very first progressive web So you've learned everything today You can go and put that into practice and we'll have the our engineering team and developers there to help you If you don't want to do that here, they're all online and you can get access to them wherever and whenever you want Which is a great thing so One other thing I do want to say is that we've got a nice range and a great range of Cross-browser industry experts are coming so we've got representatives of Microsoft, Mozilla Samsung obviously chrome and opera as well the second day will have a panel session So if you have any questions that you want to put to the team like that's your chance to actually say hey Like this is like what's the whole story of progressive web apps service workers all these types of things Like this is your chance to ask the kind of the product managers and lead developers of those teams Questions that you have about progressive web apps So please do submit questions and Jeremy Keith will be running and moderating the panel session as well tomorrow, which is a great thing and Finally or one nearly finally all of our content will be available on YouTube on our Chrome developers channel It's going to be up hopefully today So pretty much after this event is finished all the content will be available And we'll make sure the slides are available as well so you can kind of go through them and you know pull them Apart and do whatever you need with them. Like I said, we have a tightly packed agenda We do have a number of breaks 11 to 11 30 1 till 2 is the main lunch You'll be out in the main foyer again at 3 till 4 and then finally at 6 30 We have like the closing session or we finish up then but we also have like a dinner and a party in the venue as well And you all obviously welcome to come to that So with all our boring stuff out the way, it's important stuff But unfortunately, it's not the most exciting part of the whole day is I want to get everything started So I would like to introduce Alex Russell onto the stage And we also have Tau Tran who'll be doing our keynote session as well Who's our lead from the global product partnership team? But first is Alex Russell to talk about everything future the web Thanks Paul and welcome. This place is amazing. This venue is incredible I'm so excited to be here this morning with you to talk about progressive web apps But I'm an American and so I would be excited about something I guess But I think it's legitimate to be excited about this because we've got two incredible days of talks We've got codelabs. We've got Experts here, not just Chromies my fellow engineers from Chrome But also folks from other browser vendors and engineers who are making progressive web apps in the world some of the world's best experts Who are engineers just like you making this stuff are going to be here to share their expertise and what they've learned over the past year It's it's going to be great so at Chrome Dev Summit last fall we promised that we a Chrome Dev Summit in Europe and This summer and we're breaking that promise Because we thought better of it. We thought that instead of a Chrome Dev Summit We should have something that was more inclusive the web is bigger than Google. It's bigger than Chrome It's bigger than any single platform or browser vendor. And so that's why we've done the progressive web app Summit instead We renamed it and we're incredibly glad that as Paul mentioned our partners from Mozilla opera, Samsung Microsoft basically everybody is here and it's great and As I mentioned, I'm an engineer on the Chrome team I lead both the engineering side of the team that's building the progress web app stuff but also the standard side and As somebody's been on the Chrome team for a long time Let me assure you that building and distributing native software is a real pain I've been on the chrome team since before there were 1% of people in the world using Chrome We had to fight really hard to get Chrome into people's hands You have to convince someone to go download it and then once they've downloaded that to click on the thing and run the Installer and once they've run the installer They have to then choose to use your application. The same thing is true in native application platforms of any time You still have to convince users to go find your thing Download it install it and then choose to run it That's a massive challenge for any company that's trying to make forward progress Although it used to be a lot harder. This is how when I was a kid my family acquired most of its software We used a Ford tourist station wagon like this to go to a place like this To buy discs like these that you had to physically put into the computer before you can do any of those other steps So it used to be a much longer journey to get software So when I went to college it was a revolution that we were able to use CDs from almost everything many fewer discs to swap And when I got there at one point I got for five dollars from the bookstore the college bookstore I got a copy of Microsoft Map point now if you hadn't used map point that's okay Not many people had but map point was a bit of consumer GIS software You could have a map on your computer that you could pan and zoom around it only took 30 minutes to install But it was an enormously Transformative experience you could just zoom around the entire world if you needed to Yes, the data got out of date, but it transformed the way I plan trips Especially road trips kind of an American thing, but very very timely for me in college And at the time web based experiences just couldn't compete if you clicked on the link to go to a bit to the left You then sort of waited and then oh there it was Even though the network was pretty fast. You still sort of did this stuttering back and forth It just couldn't compete. There was this big cliff between what you could do a native one you could do on the web Then Google Maps happened we eventually got pan and zoom on the web It worked on any computer not just the ones I'd spent time installing the software on and the data was never out of date Maybe it wasn't entirely complete, but it kept continuously getting better And I didn't have to go get another CD or download a big patch. It just was always fresh So when the web is capable of delivering a particular experience it can compete our distribution model is actually better links Are the webs superpower So okay quick I can see everyone so a quick rate raise your hand if you use the web to get to maps on your desktop or laptop computer Yeah Okay, and I keep your hand out. That's almost everyone keep your hand up if you use the web to get to maps on your phone Okay, so so less okay. Yeah, okay 10% sure that's about what I thought so We don't really use the web on mobile the way we Used it on desktop, but remember that we started with native apps on desktop, too So what we needed to break the log jam between native and the web on desktop was some enabling technology and Ajax was that enabling technology it allowed us to Move data in as you panned and zoomed around the experience. We did the exact same thing for email I don't know about you, but I moved almost all of my mail consumption to a web browser on the desktop But I'm using a native app on my phone So why haven't we made the same transition on mobile? You know, I think just to reinforce how big the size of this this cliff is today users are spending almost 90% of their time on native device on mobile devices in native applications Why is that well one theory is that maybe the re-engagement features that native apps have had keep users in those experiences Or draw them back into it things like being on the home screen or notifications that can be persistently in your notification tray but It's a huge Amount of time and it's hugely concentrated if you haven't won the lottery for native applications You're probably not going to because users are spending 80% of their time in the top three apps That's 80% of that 87% this is a huge winner-take-all dynamic, which we didn't necessarily see on the web If only native apps can be engaging and only a few can make it on native. Why hasn't the web disrupted this? It often takes more money to distribute a native app to a user on native platforms Then you'll get back from that user like native app developers are suffering. Why hasn't the web disrupted this? So I think it's worth the thinking back again, you know a decade or so to think about how we used to get web experiences I don't know about you, but this is how I got web pages You dial one of these up you'd put you go to the bit of your house That had the computer in it and you'd put the computer into online mode and you'd Eventually you wind up yelling up or down the stairs to your friends and family like don't pick up the phone You're going to interrupt my download This was tough, but we knew we were in online mode and the web grew up in an online mode We could always assume that that next navigation that next transition no matter how slow It was the first time was going to be the same speed the next time, but that's not how phones work Phones even when they look like they're online they often aren't radios Transition wildly underneath us the network isn't reliable. We can't assume that it is Ajax got us to good enough because we were always connected, but what about now when we're not always connected When I'm on a mobile phone and I tap something from my home screen I never see one of these apps always load Maybe they tell me that they don't have the data that I wanted or they can't get the new stuff But so they'll show show me the old stuff, but they'll never give me this cute little offline dinosaur They have this UX contract that they'll never fail to load if they're on my home screen The web hasn't been able to do this We've also made the keyboard to and mouse to tap and swipe transition But I think that one of the biggest issues here is that we haven't really earned our place in the home screen because web Technology can't be reliable and can't be reliably fast. It's reasonable for users not to include us in their daily experience So one way to think about this is There's an axis here of capability now native apps have the ability to start up reliably They can be fast all the time they can do offline. They can handle push messages They can synchronize in the background. They've got access to all the sensors While the web is safer and more respectful of your privacy, but it doesn't have some of those capabilities It isn't on your home screen. It isn't in your notification tray What if we had another axis? We'll add reach The web succeeds wildly here even in the situation where users are spending only 13 to 14 percent of their time on their phones on The web they're visiting more than a hundred sites a month Meanwhile Com score says that the average user is downloading zero apps a month in the US This is the power of URLs. We can absolutely meet those one-off needs and we do we are always in the user's Experience even if they don't realize it So what we want is a way to go from incredible reach to be more engaging to have those capabilities So what is that thing I? Think we can meet those user expectations today on the web and that's what progressive web apps represent They're finally the ability for us to earn our place in the home screen and in the notification tray first by providing Reliable experiences that are consistently fast and we don't have to give up the reach to get it That's the promise of the web and that's why I'm excited about progressive web apps So what are these experiences look like so here's the Washington post comm slash PWA you can go do it on your phone right now Wapo comm slash PWA and it loads like in a tab like any other site And if you go to it enough if you engage with it You'll eventually get this add to home screen prompting chrome for Android So if you tap on that link the browser will confirm to you that you've done it And if you go back to your home screen, you'll see that there's now a home screen icon when you tap on that icon It's beautifully fast and it'll launch with a splash screen that splash screen is a full screen immersive experience And the whole app runs that way and if you go into the task switcher what you'll see is that it's first class there, too There's no URL bar getting in the way. It's exactly like a native app in that sense. So What was missing to be able to deliver this experience because we finally earned it? well first we need reliability and reliable performance and Next we need to be in the notification tray and lastly once we're trustworthy and have reliable performance We need to be able to have enough metadata about the site to be able to generate that add home screen prompt to put it on the home screen Okay, so there's talk today and tomorrow covering all all of the required technologies to get to that point TLS Which is imperative and HTTPS manifests service workers push notifications smooth UIs and much much more and I'm excited that we've been able to work with other browser vendors over the past three years to deliver these technologies to you They're already shipping in Chrome opera Firefox it's amazing stuff and they're going to be an edge soon So the web is bigger than any vendor or a single platform It gives you that incredible reach and we're bringing this stuff to every browser So but I would just want to focus for a second on reliable performance We all know the faster is better and if we have to traverse the network We can almost never be fast specifically a mobile network where getting the radio initialize can take two seconds The data from so acid that you just saw really confirms that correlation between speed and bounce rate But we see that a three-second delay can bounce 40% of users It's really tough out there if you're trying to deliver great experiences on the mobile web So what if we weren't necessarily going to have our connection eaten by the offline dinosaur? What if if a user goes to the site it could be reliable after that? That's exactly what service workers are they provide an in browser programmable network proxy so that users can Always get to something on your site the second third and fourth times They visit if they are willing to re-engage with you They can always get to your experience and you can use your own cash to do it You can always boot up without ever hitting the network you can provide an experience from local data This is exactly what native apps do and this is transformative for the way we deliver reliably performant experiences So what about that first visit? Well, the search team has been thinking about this because there's a epidemic of obesity on the web and they came up with amp amp is a Format that uses custom elements html custom elements web components to keep you from doing most of the things that really hurt the user Experience and it delivers incredibly fast initial loads They're seeing median one less than one second load times from the amp documents on their CDN Which is generally four times faster than the same document? Hosted in a different format and it's often ten times less data That's pretty great So what of those a way to go from that fast first load using amp to that reliable performance that immersive experience with progressive web apps So here's an example of the Washington Post today If you go to Google news and you see that amp carousel and you go to an article You'll be reading it inside the CDN hosted version So it's not on the Washington Post servers But while you're reading it the amp install service worker element will go and install the progressive web apps bootstrapped service worker from the Washington Post so now if I click a link from this article out to someplace At the Washington Post instead of the offline dinosaur. I'll get a reliable service Handled by the service worker and it'll load instantly. This is pretty great So this is also leading edge stuff and it's been hard to do until recently dev tools are evolving very fast and this is the new application tab in Canary and Chrome dev which helps verify some of this stuff, but as good as this is Wouldn't it be great if there was way to do this at the command line or in your CI? That's what lighthouse is for lighthouse is an exciting new tool that gives you a Chrome extension if you want it That can help verify that you've met all the requirements to get to that add to home screen prompt And it's also available in a command line form so you can run it as part of your continuous integration So there's a ton of new capabilities that are coming to the web that unlock other sorts of applications Once we've earned that right to be on the home screen. There's too many to talk about I'm incredibly excited about web assembly and what web GL are two are going to do this year for games and what media caption streams Are going to do for social use cases, but there's two specific capabilities I want to talk to you about that you'll hear more about later today from Chris Wilson That I think are going to really really make it so that the web is a first-class citizen The first is the web payments API and the credentials API follows that So what payments what's that so web payments is a way for you to not have to fill out forms with the worst keyboards in the world When you want to check out on the web it lets you do one tap checkout using cache data that the browser already has so here For instance is a Shopify checkout flow. I can tap the check out button And then I'll get a pre-populated list without ever having to fill that stuff in and if it looks good I can tap it and then I'll be getting a confirmation Screen it all worked. I didn't have to enter any new data. That's pretty great In fact if Android pay or some other System-provided payment instrument is available and the site supports it. This can go as simple as a single tap or a confirmation I think this as a standards-based way to get this capability available pervasively shipping this year is so exciting Similarly the credentials API is going to also remove a bunch of Typing and tapping and autofill corrections and all that stuff that isn't great to do on phones Like native apps will be able to do one tap sign-in if the site knows who the user is it'll be able to request Using existing system credentials that the user log in and that can be a single tap In fact if the users already been there this can be automatically done This is going to accelerate how we deliver first-class experiences on the web in addition to all the progressive web app technology That browsers are already shipping now you might ask how is that stuff doing and I'd say well, but I think I'm incredibly biased But you don't take my word for it to tell you more about how it's actually going I'd like to invite my colleague tau-tran from the partnerships team to take a look at how progressive web apps are performing in the real world Thanks Thanks, Alex. So as Alex mentioned I work in global product partnerships for the Chrome and web platform team so that means I get a chance to talk with lots of different companies and sites and To tell them about all the new web capabilities today building progressive web apps that are going to be reliable fast and engaging Experiences and I often spend a lot of time with partners thinking about helping them think through how do you develop a mobile first? strategy for the web So Alex really walked through a ton of kind of new capabilities that are available today and you'll hear a lot more over the next couple of days So the whole point of coming to these conferences is that we want you to get excited and motivated To really want to build new things to start digging into these APIs Tinkering with with all this new stuff and so it's kind of like a kid kind of playing around with a new toy And so this is my three-year-old the first time we introduced play-doh to him And he thought the possibilities were endless in terms of all the things that he could make So I had to choose between a kitten or my son. So I decided to go with my son So so you know, he's he's like being extremely creative He even was trying to convince me that green play-doh pizza was gonna be so good And so this is the type of energy and creativity that we want you to bring back to your teams and to your company But I also realize is that the reality is that when you get back to your companies You're probably gonna have to pitch and talk about how you want to start a web project I know many of you have probably already started looking at these technologies and you may be getting questions from different people inside your org Like how much time is this gonna take? How many resources it's gonna take. What's the ROI? You know all those like annoying business and resource type questions and I hear it a lot from our partners And so what I want to do is actually give you a framework for how you can think about You know building the case for investing in the web and so Oftentimes, I think the dreaded question that every developer You know gets is okay Build me a business case for why you want to do this project and as a developer that's kind of code for actually don't try anything new So you start feeling like this So for those of you who have kids, I think this is a very familiar This is when he's in a tantrum mode when I ask when I ask him to do something. He doesn't want to do it But in all seriousness we want to help you build a case for the web And the goal is to walk away from the next couple of days where you can actually talk about new capabilities And make the case for why it's critical to invest in the web platform So I thought about all the learnings I've gotten and all the feedback I've gotten from you know all the different partners across the world and When people say hey after prioritizes I need to figure out how this fits into my roadmap It basically boils down to two critical questions. Why is this important and? How do we get started and a lot of times partners just want to have an understanding of you know What are some numbers that you can share and what are different approaches so that this feels accessible and feels like I can scope this for my team and So to talk about what's important or why is this going to be important? I'll just give kind of a brief overview of some key metrics that folks on the business side often like to think about reach acquisition and conversion So the first one is reach and here we'll just take a look at the overall mobile web market and see if it's growing Alex talked about how you know people are spending so much time in in apps and so what we want to take a look is just to see What the mobile web audience looks like so we'll take a look at some of the Chrome numbers that we announced last month So Chrome announced that we now have a billion monthly active users on mobile alone This is incredible for a couple of reasons one for those of you who may not know Chrome on on mobile was only came out about four years ago and This time last year this number was only four hundred million monthly Actives and so what you're seeing is that there's tremendous rapid growth on the mobile web and Then we look at reach drilling down to more site level data com score data taking a look at the top thousand apps and websites and Comparing monthly traffic for apps native apps versus the web and not surprising. It's two and a half times that The reach of the mobile web is two and a half times that of apps. You can probably see it in your own numbers So it's worth kind of digging in to understand what your overall mobile web Mobile traffic is and then break it down between your web and app and now don't agree I've heard partners say somewhere between 50 to as high as 90% of their mobile traffic actually is on the mobile web So now it's just been another minute on acquisition So you have this incredible reach and you still need to bring users to your site And this often sits with the marketing team or your growth teams But when you're trying to make a case for investing in the web You should understand all the different forces that play here And so with acquisition oftentimes you're probably paying to get users to your site So it was really cool when we saw that serial which is a platform for buying and selling goods It's a startup actually publishes that about user acquisition costs They started building a progressive web app and then saw that the engagement numbers between progressive web apps and Their native app was comparable And so then he the CEO started digging into well if it's comparable from an experience standpoint How much is it costing me to get a user into my native app versus the mobile website? Turns out it was ten times cheaper to get a user onto their mobile web experience So for those of you who are familiar with acquisition costs This is probably no surprise, but it was really great to see someone dig into the numbers and then share it publicly So the next piece after conversion. I mean after acquisition is are my users converting so it's awesome I've reached the coming in and but am I actually getting them to Frequent my site more or conversion could also be defined as completing a transaction when the money really comes in so Aliexpress launched a progressive web app last month during IO and It was incredible to see within days of them rolling out their progressive web app experience They saw huge increases in engagement numbers two times more page views 74 percent increase In overall time spent across all browsers And what was telling was you know, we often get the question about Safari on iOS And is this going to be a good experience across the board, especially if they don't yet support progressive web app features So we actually asked Aliexpress to dig into their conversion numbers Which they saw increase across the board but to segment it for iOS specifically or Safari specifically And they also saw an 82 percent more conversions on iOS And it just shows that Aliexpress already had a good mobile experience But they continue to invest in it to make it more engaging and fast and immersive and Their iOS users also benefit So it's just good all around to actually invest in your mobile web experience and to make sure that you know You actually deliver experience to users on all platforms And so this really cemented I love this quote that from the head of mobile at Aliexpress Which you really just talks about you know building you know investing in the web experience across all browsers And not only did they see huge benefits on browsers that support progressive web app features they saw a bump across the board and it's just a sign of a really great investment and They'll know it'll pay off once other browsers continue to evolve and ship these APIs And so this is a model that I thought was really great. I can't take credit for it My colleague put this together So when you think about all your potential reach bringing people in Hopefully at lower acquisition costs or likely at lower acquisition costs for the web and then you're improving conversion Start to like a look at take a look at these numbers and they add up to pretty good math profitable math I assume And so this is just a think a way to for you to think about why it's so important and why it's great to invest on on the web And so then the next question and this is One of the tougher questions to try to handle is how do we get started? So a lot of people say to us, you know, these technologies seem really intimidating Especially as I'm talking to my management team So how do I can so do I have to convince my team to do a complete overhaul and the short answer is no Alex painted a picture of what's possible, you know Giving you a vision of where we want the entire mobile web to go with these amazing experiences But we also recognize that it's complicated to bring in these new technologies Especially at larger companies where you have sites with legacy code and architecture And so we want you to think about this as an ongoing journey to invest and build on the web And so the first step is HTTPS which Alex already alluded to and my colleague Emily Schechter We'll talk about kind of myth-busting through HTTPS later today But it's it's critical because all these new features will only be available over HTTPS So it's not already on your roadmap. It should be So now now I want to walk you through partner examples and how they've actually approached Building and experimenting with all these new web technologies So the first one is starting from the ground up So this is you know when you're able to just rethink or re-imagine what your mobile web experience should be I know very few sites actually get the opportunity to do this But when you do you really are able to unlock so many of the capabilities of service worker And all these amazing features And so I want to talk about conga conga is actually one of the largest e-commerce players in Nigeria and they decided to do a rethink of their mobile web Experience and just build and basically build a progressive web app that was going to be very comparable to their native Experience and actually the director of engineering Andrew is going to lead a session talking about how conga is approaching their progressive web apps Building tomorrow But what was really great to hear yesterday was that this was a cross-platform effort Even though they were building a progressive web app, you know They're iOS and Android teams really collaborated to make sure it really truly was an app like experience on the web And so the conga experience, you know not surprisingly is focused on being fast and performance and reliable and The most critical thing for their users is making sure it doesn't use a lot of data And so in early testing they saw that for initial load it actually used Comparing to their native app experience it used 92 percent less data for their progressive web app And then that critical moment of converting the user to actually completing a transaction They saw that actually used 82 percent less data as compared to their native app So again seeing terrific stats when you're able to kind of invest end-to-end and then start from the ground up But we also know I mean as I mentioned it's really hard to catch Company at a moment when they're actually going to rebuild something or going to change, you know architectures or frameworks And so I want to offer Why don't you build a simple version and a couple of examples of how that's being done? So air Berlin did this demo at IO, which I thought was terrific They knew they couldn't change the entire site experience And so they thought about well is there a segment of my site that I can change or convert into progressive web app? And here they looked at the post booking experience So imagine like so the pain point I think that we all recognize is that when you were at the airport your frenzied You want to just easily be able to access your boarding pass Your itinerary information may be your destination information But the connectivity is pretty unreliable and so they wanted to have this customer journey details Available offline and so they used they leveraged service worker caching to enable this and what they saw was that the initial loading time Was less than a second because they've done a ton of optimizations But even faster with service service worker for subsequent loads And so even if you're offline or you land and you're in another country where you don't have Wi-Fi access all your Destination and itinerary details are available on your device So Alex talked a lot about the Washington Post earlier And you know we got a lot of questions about how do they you know, why do they build this? You know, when are they gonna transition into a bigger or a more productionized site? And so the post you know what they wanted to do was they wanted to do a public live demo To show what's possible. So they took their top stories news feeds and said, you know Let's go ahead and just build this really fast immersive experience And they wanted to be able to show it off publicly but also internally as you know folks who are in publishing newsrooms Different people in advertising their executives And what they saw was that you know, everyone is obsessed with speed at the post And in their progressive web app they saw article page loads times inside the progressive web app hit 80 milliseconds So now that's the bar and that's the user experience. They want to deliver and I'm happy to say they're actively Exploring a roadmap of how they're going to evolve this to that. It's going to be available to a broader set of their mobile web audience But even sometimes building a simple version or getting a site or a section of your site to a progressive web app Could also be hard and so we've seen people just focus on a feature Pick an API or a feature that you believe will have high impacts for both users and your business So the weather company folks we know familiar with weather calm You know, they've been looking at progressive web apps for a while and all these technologies and what they wanted But they were asked to prioritize. What's the one feature? That's really going to be Great, you know ROI And so they decided to go after web push notifications And what's really great is that they went big on this one feature they launched about a month and a half ago and they actually launched in 30 languages globally with web push notifications and what you see here is actually the How you can decide which type of notifications you want local national or government issued alerts By the way, these are all notifications that are available in their app So they basically made it parody with the web or make the web on par with what app notifications were and Then booking comm as you know a major travel player Where you know, they had been looking at all these technologies and they ideally I guess we could try to build a progressive full progressive web app But that doesn't work for their business. They they're extremely data-driven They test everything and so they needed to work in small steps so that they're able to tackle different issues Learn things quickly test and optimize. And so Jesse Yang who is quoted up here Is going to actually lead a session tomorrow talking about bookings approach on their journey to building a progressive web app And so I really want to You know emphasize that everyone will take their own path whether it's building from the ground up doing a simple simplified version or Using a single feature There's no one-size-fits-all and I want to make sure that you do the path That's right for you and so that it feels accessible So these are just a sample of partners globally who have started shipping or actively looking at These progressive web app technologies and again, no one partner has done the same approach They've again modified it and really thought about what's important for their users in their business As they're thinking about investing in the web and to help you with this journey of building progressive web apps We're pleased to announce that Udacity now has a nano degree program And it's an extension of the senior web developer and developer nano degree where it's a short series of classes and projects And then you'll complete when you complete the course you'll be able to architect and build app-like experiences on the web So in closing, I guess I did have to include a cat in here, but in the corner So it's amazing to see so many people here. I was just commenting to the Chrome team Backstage that this time last year. We were just talking about service worker and the web push API and Progressive web app as a term was still being socialized And so it's incredible that I'm standing here today about a year later where we're have a dev summit dedicated to progressive web apps So we've got an exciting lineup as Alex walked through so we'll hopefully you'll stay for all the different sessions And at the end of it, we want you to leave the progressive web app dev summit really inspired and confident about building the case for the web And more importantly, we want you to go build something great. Thank you and Next I want to introduce to you Jake Archibald and if you haven't been awake yet You should wake up because there's actually code in his presentation That music's great, isn't it? I love it. It's like one of those kind of corporate Business intros where we're gonna actually play it again. Go on. Can we play it again? Can we press the button that makes the music happen? I Assume it's just a big button that is like corporate music Okay, right still I have everything plugged in now. I've got to click it see it. Okay, so a lot of times when people do these kind of Pools of an audience that they ask people to raise their hand. It's kind of totally meaningless It's just to kind of make sure you're all awake, but I'm gonna ask you a question and it's actually going to it's gonna decide the talk I give So here goes who here has sort of seen a talk about service workers before or kind of know roughly what they are Okay, right, so I'm not gonna do the intro talk then So if you don't enjoy the talk that I'm about to give it's actually your fault you picked it So you should have picked the other one So firstly, I'm gonna do a little bit of a recap I built a little web app a web app called emoji which you you can find at this URL It started just as a website But I turned it into a progressive web app and if you're looking to do the same thing The first thing you need to do is to integrate the site with the operating system and the UI And one of the ways of doing that is in the head of the page You can use a theme color and your Chrome will use that to kind of change the color of the location bar there So it's a small quick win for integration, but the main part is this web app manifest So inside the manifest it looks like this It's got details on the the name of the app the icon all that sort of stuff And once you have this usually be able to add the site to their home screen and they get the icon and the name That you specified but not only that when the user taps that icon they get a splash screen This is reasonably new in Chrome And this is while the browser is booting up and while your page is getting to first render And so the icon the text there and the background color and the sort of the purple strip across the very top there That's all taken from your manifest so you can configure all of that and once that goes away You get your site, but without the URL bar or that's an option you can have so here It just it feels like a native app However, this whole illusion of native comes crashing down when you're offline So this is pretty bad right the user has launched our app. They've come back to our app They've added it to the home screen. That's how much they like it But we have failed them to such an extent that the browser has had to step in and defend us And they do this by blaming the user saying you are offline. This is your fault If we're gonna compete with native This is this is like an operating system level error message like a full crash So this is not good enough, but things get worse. So offline isn't the worst thing that we face This is I Call it live fi This is when your phone says it has connectivity, but it doesn't really I think we've all experienced this that the live I experience Is just that So that the splash screen goes away when the the site gets to its first render But with li-fi that never happens that this is worse than offline with offline You get a quick answer. The answer is no, but it is a quick answer here The user is just left waiting you're forcing the user to stare at this or give up and with every passing second They hate the user experience a little bit more And this is why we should avoid treating online and offline as these kind of binary states Because if we cater for online and we cater for offline as separate things This situation goes completely unsolved And that's why the gold standard here is offline first offline first solves these problems with offline first we assume offline and do as much as we can with local content Then try and get content from the network and the more we get to render without a connection the better So you should think of the network as a piece of progressive enhancement enhancement that might not be there and Here's how we do it So to begin with register for a service worker and this isn't some kind of magic manifest format It's just JavaScript Because before why do we invent a whole new thing when we've got like a room full of JavaScript developers go a world full of JavaScript developers and loads of existing tooling of Course we should write this register call here in a simple feature detects because you know, there are older browsers out there That don't support service worker and this feature detects prevents them from hurting themselves and others around them Anyway in that script, I'm just gonna register for this event this fetch event So I'm gonna have a debugger statement there and when I do that now if I refresh the page I hit a break point and you get this event object and it has a request property And this is the request for the page and you get things like the URL the headers the type of request But you also get one of these events for every request that the page makes the CSS the JavaScript of fonts that the images I get the event for these avatars even though they're on another origin So it's it's not just your own origin So by default requests will go from the page to the network and there's not a lot you can do about it But once you introduce a service worker, it controls pages and requests will go through it But like other events on the web you can prevent the default and do your own thing and that's where things get really interesting So let's use that to go offline first So the first thing we need is an application shell which is just the site But without the messages in this case We want to serve this and the CSS that requires and the JavaScript requires before we even try a network request before We even think about going to the network Because even if you have a great network connection serving this locally is going to be faster and that's the offline first approach So we need to cash this ahead of time and the service worker has an event for doing is it's the install event This is fired when the browser sees this version of the service worker for the first time It's your opportunity to go and you know fetch everything you need to work and store it in a cache So here I'm opening a cache called static v1 and then there I'm adding the HTML for the shell the CSS and the JavaScript that it needs But these won't be used by default service worker doesn't do anything for you It kind of it waits to be told what to do so over in the fetch event I'm going to start by parsing the URL so we can look at the component parts of it And then if the request is to the same origin and it's just slash I think it's the home page We're going to respond with the app shell from the cache So calling respond with here is is my indication saying like I'm going to handle this request I'm going to take over here And we pass in either a response object or a promise that resolves to a response Caches dot match that that that returns a promise which resolves of a response from the cache So these composers together really well Otherwise we're going to try and respond with cashed content that matches the current request So that's how we're going to pick up the CSS and the JavaScript when the shell page requests those if there's no match It's going to resolve with undefined So as a fallback if response is falsely we'll make a network request So this is the offline first approach retreating the cache as our priority as our primary source and then falling back to the network Whatever connection the user has So using this pattern, you know the page goes to the service worker The service worker just pulls the the shell from the cache and the CSS and the JavaScript it needs So that gives us our shell render without going to the network and now we're running JavaScript on the page So we can display even more content. So with a mojoyer in this case I actually went to index DB and pulled out the past messages the last messages the user saw and Render those on the page as well So the user's looking at messages without having to go to the network and then we can go to the network for newer messages If we can and we can show update content and additional content So if this network request fails it doesn't matter because we're displaying content That's a good offline experience if a network is slow Then that's maybe okay because the user might just be looking at past messages and we've given them that So to see the benefits of this, let's pit the original online only site against this new shiny offline first version We must go to the comparinator There was gonna be sound there never mind So first up the online experience Go so we get instant full content. Why is the original lags behind having to fetch stuff from the network? What about the offline experience? Well instead of complete failure. We have instant full content What about li-fi? Instant full content rather than the white screen of death In fact with our progressive web app the experience is the same no matter what connection you have and that's the offline first goal The network only matters when it comes to fetching new content And this is how we compete with native and compete with native. We can I decided to pit the Emojoi Progressive web app against a native app Google photos in this case because it's a well-built well refined native app I just wanted to launch them at the same time and see what happened. So press them at the same time And it's really close. This is native versus web And in fact the mojoy is about naught point two seconds slower to show content That's 200 milliseconds not a lot and that's compared to a well-built native app But that's starting from cold the browser isn't in memory If the user who's used the browser sometime recently and let's face it the browser is a pretty popular app So it's likely to be in memory. This happens This is a progressive web app beating a native app to content render by almost half a second Now a few people said to me it's like well, what about Android instant apps? What about those? Well, my answer to that is progressive web apps are shippable today And they're not Android only you can build one app across thousands of devices operating systems and browsers And it can beat a native app to content render So service worker is in the stable versions of chrome firefox opera Samsung browser as well, and it's coming to Microsoft Edge. It's a high priority implementation for them It's under consideration by Apple But progressive enhancement means you can use it today. You just don't get the offline features in safari But if you use service worker and suddenly your stuff has more features or becomes faster in chrome and firefox Then that will give Apple more reason to implement service worker as web developers you are in control of the future of the web here But not enough about the things that are supported today I want to talk about the future is what I wanted to get on to because I built another app. This is This is fun Let's try that again. We can have a disco. This is great, isn't it? So if someone from AV can sort that out, I'll I'll start talking around the thing I built That would be fantastic. So Wiki offline, it's a kind of psychedelic experience based around drugs So the idea was to build something like Wikipedia but Wikipedia that ran offline first so It's something that it was very much very less of an app because the emoji is very much built like a native app It looks like a native app, but was it is this stuff applicable to sites? Like is it something that you will be able to use for your blog? And we thought Wikipedia is a really a really good demo of that. So the idea was like when you're online You're going to get a server render because that's how Wikipedia works But with a service worker that we can we can start doing different things Okay, so It's great because I've got the previous slide from the last talk staring at me So I've just got a dog saying go build is like no I can't I've got to give a talk at some point hopefully the So part of the the challenge that we had with Wikipedia is that it was it's a different model We've got this this server render going on. I've got my notes up. That's great. That's a good start Will I get slides? So the first thing I did when I built the Wikipedia demo is is to create an app shell as well That's good. We've got it on this screen Come on. Give me slides. Please My hero This is great Why me why is it always me? Gonna get a new laptop right so hopefully my impresses button slides gonna go forward. That's right So I built an app shell for the article pages It would load this generic shell without the network and then the pages JavaScript will handle affection is the appropriate from thing from the network so Without service worker it was kind of just a standard website But with service worker I'd re architect re architected it to be more like a single page app So I was dead excited about what I built so I ran straight to the comparinator to see how it you know everything changed So I'm gonna set the the normal website here Against my shiny service worker version and I'm gonna load it over a fraught internet connection Or as most of the world call it their internet connection Three two one go and I watched this and I thought shit It got slower like way slower here is again first render is actually quite fast But the content which some people would say is the important bit Is over two seconds slower on 3g now? I had a mild panic not as much as the panic I just had two minutes ago, but a mild panic that we'd really messed up this service worker thing But it wasn't service worker. That was the problem See I was using this app shell and letting JavaScript do the rest Which is fine if your design already sort of dictates that you do something like this, but it wasn't the case here I'd re architected a site into a single page app and single page apps are incredibly slow And this is why you'll see me moan about frameworks all the time on Twitter Here's what a website does to get to first render HTML starts downloading CSS downloads And now we start rendering content and we render more as more HTML downloads We might download JavaScript as well, but it should be a sync so it's not going to block render Contrast this to same a single page apps web apps where HTML downloads usually instantly because it's normally really small CSS downloads and then we get our first render assuming the JavaScript isn't render blocking which it often is but let's be kind Anyway, this is just a basic UI render no content and then JavaScript downloads it parses and executes and then it goes off to fetch the content and once it has all Of the content it adds it to the page and we get to render and this is this is how slow happens You know and in my case I wasn't losing too much time on the CSS the HTML and the JavaScript download because they were all cached in the service worker But it's the problem here is at the bottom the JavaScript has to download all the content before showing any of it The more I think about load time performance the more realize it's not about the size of your CSS the size of your JavaScript It all comes down to being progressive and this is related to progressive enhancement But not quite the same. I mean show them what you've got like at the all the time you're loading You know the user is watching and waiting Don't make them wait until you have everything before showing them anything Prioritize the first render the first interaction show the use of what you've got as you get it And that's where I was failing I was hoarding all the content and only showing it once I had all of it In retrospect it seems kind of stupid to cram a site into this single Page app model, but for me. This was my apcash hangover. You see apcash nearly Nearly lets you use the page shell pattern, but not quite But it lets you so close like you can almost smell it But it just sort of bats you away at the very last moment So once apcash was out of the way. I was like Really? Apcash is gone Does that mean I can have all of the page shells I want and nothing is going to stop me? But I didn't stop to think that the best answer wasn't the one that apcash Nearly let me have it was the thing that it didn't let me anywhere near What I wanted was streaming And with streaming you get to finish the is a simulation here and you can see the sort of final render is Somewhat quicker than the non-streaming version, but the important bit is that ah render happens Ages beforehand than the in a non-streaming model So this is the full html spec loading here over a throttled internet connection like it's a three megabyte document It's still downloading, but it gets on screen after only 20k is fetched. Which is great. That's streaming But for a long time we had no access to streams and JavaScript, but that is all starting to change So we designed the fetch API Longside service worker mostly because we needed a lower level representation of requests and responses But it was also a good opportunity to kind of to look at xhr and make something that's a bit easier to use because xhr It's almost 18 years old. I don't want to be using xhr when it's legal to drink, you know, it's bad enough when it's sober So this is this is fetch It returns a promise for a response there it is But that that only resolves when we've received headers We haven't received the body yet You have to choose how you want to read it and that gives you a promise as well And then you get your data adjacent in this case This compress is really nicely using arrow functions and even better using async functions So that the keyword await there it pauses execution of the function until the promise resolves and it's paused in an async way So it's not blocking the thread. It's not blocking interaction. I think so edge has this in their preview builds I think we've got stuff in canary as well But babe will let you use it in other browsers as well and it produces much easier to read code I think it's great. So if you haven't encountered it before You can you can pretend that async code is is sync makes it a lot easier to read Anyway, you don't have to read the responses Jason We added a load of different methods for common types of you'd want to read and we added these for two reasons like they're nice convenience methods But we wanted to ship Fetch before streams were ready. So we needed a way to read the body But we did reserve response dot body first streams when they when they landed and they landed in chrome and opera around a year ago And they've been actively developed by Firefox edge and even Safari as well that they're working on them Here's how you use them So you fetch something say the HTML spec and we're gonna fetch it as a stream and we call get reader So I'm saying I want want to open the stream I want to get a lock on the stream and then we can read some of the data read returns a promise Result is an object result dot done is true when there's nothing left in the stream so If result dot done isn't true result dot value is a chunk of the data and that's a you in a array of bytes that you've received It's not the whole response. It's just the first part of it and when we want the next part we can call read again So if you wanted to get the length of a whole response We could do this, you know We're gonna have a variable there to keep a running total and then we're gonna create a loop I'm just gonna keep calling read until result dot done is False and in there get the value add the length to the total and then log it out And that's it done. We should be able to see that working. I don't know I Feels really risky doing life demos after what happened before but let's give it a go. Let's see. Here we go. So this is Let's see if I can make this bit bigger. Oh wrong window Maybe I can't make it bigger. Where's my mouse pointer? There we go So if we refresh the page here We can see the sort of log at the bottom there and it's reading the HTML stuff and we can see that the We're inspecting parts of the response here, but we're not having to keep it all in memory You see the chunks are of different sizes. So that's something you have to deal with They're kind of around about 32k, but not always So here we're reading that the full size. It's eight megabytes I think the uncompressed size right down at the bottom there, but we don't have to have the whole thing in memory We're just sort of reading bits and then they can be garbage collected straight away So a more practical use of something like this would be to search a stream for a given string So say we wanted to search the HTML spec for the word horse. Here's how we do it so This is fairly a simple way of doing it We're kind of fetching it reading it as all this text and then searching But this means we have to load that full eight megabyte document into memory and then search across it We can do better with streams Instead of fetching all the text loop over the stream as before But the problem here is that result dot value is in the ray of bytes Whereas we need a string to do the matching in future This will be really easy You'll just be able to pipe the stream through like a text decoder and that will kind of read in the bytes convert It to text and pass out the other end But transform streams haven't been fully specced yet They will come they're coming soon But at the moment you can do things a little bit manually with with text decoder So here we fetch get a reader but also create a text decoder and then we'll loop through the stream as we did before But on result dot value I'm going to call decoder dot decode and that'll take the bytes and gives a string back Decodes it assuming utf8. There are other options as well the stream true there. That's that's actually really important That changes how things work. So let's let me show you that so here's a simple demo. So this is the The code you saw before I've got three chunks of text there and for each one I'm going to decode each part and if I run that Everything is broken But if I add that stream option in and run things again We get the poo emoji the toilet emoji in an exclamation mark So the reason this happens is that emoji of four bytes long In utf8 so with stream true it tells it that you know it should it might be receiving more Bites later as part of the same message. So we're stream true It receives the first three bytes and it goes this is part of a character This is not the whole thing. So it just returns an empty string and it holds those three bytes the next time we call it It adds the next three bytes on so it adds the 169 the first byte and it goes ah, right I've got enough now to show the the poo emoji So I'm going to pass that back and I'm going to hold on to the last two bytes And then we add the next chunk on the next three bytes and it goes ah, right I've now got enough to for the toilet emoji send that back and also 33 at the end there as the character code for an exclamation mark so you can send that back as well so Now we can check these chunks as they come along now We've got them as text to see if it contains the word horse and not only that We can also cancel a download when we find it and this is really efficient So if the it's an eight megabyte document, but if you find a match in the first 20k, that's great We can stop the download and save all that bandwidth, but there is actually a bug with this implementation It works fine if our chunks are like my lovely and then horse running through the field Oh, there's the match in the second chunk great But what if the chunks are my lovely her No match or it's running through the field. No match We miss it because the the the match was across two chunk boundaries So when you're doing things like searching or filtering streams need to defend against this and the way we do it Is by keeping a buffer that is the size of the thing we're looking for minus one So in our case horse five characters. We need a buffer of four So that means that we you know, we could see my lovely h fine And then we keep those last four characters and add them on to the next chunk and then we see horse So the code for that My slides have gone off again. Isn't that great? Whatever you did, but oh, it's back excellent. So the code for that same as before but we create a buffer My heart rate is going so fast So we're creating a buffer. We're gonna loop through the stream We're going to decode it add it on to the buffer and if it includes horse great, and then we you know cancel Otherwise, we reduce the buffer down to those last four characters So now we're searching a large document. We're keeping the memory usage down and we can stop the download early So I'll show you an example of that as well. So we're actually going to run this on on the HTML spec It's a slightly longer Piece of code because I'm going to keep a larger buffer so I can show the search term So with horse, which I didn't expect to be in the HTML spec But if we run it through there's a match and it's because Tommy Fawson is one of the contributors and he's got a horse in his name Let's run a different example someone give me an example of something that probably won't be in the spec but might poo Do you know what that means you were so much more polite than the meetup in London that I gave this same talk to very Recently because when I asked for a suggestion There was actually a lot of silence for and then someone at the back of the audience to sort of stood up and pointed at me went shit Okay, I'm gonna pretend that's not a heckle and I'm going to go to do that sort of nervously. Okay, this will be fine Obviously, you're not expecting anything to happen. But as it says, whoa, there's a match. Holy. Oh, it's because it's a canvas shit region Okay canvas hit region. Okay Where are my slides? So Oh, yeah, I was talking to some developers in India and where connectivity is quite poor and They were sending this bit a blob of Jason down for some search results and they wanted to detect 2g versus 3g So and the idea was like oh if they're on 2g we're gonna send fewer results because it'll you know get on screen faster You'll get a faster render But detecting connectivity is really unreliable Especially in India where you can you can have 3g or 4g package, but it will be the speed of 2g So it's much better to do something else like serve something like this where it's not Jason But every line is a Jason object and this is something you can stream then you can pause each line separately as Jason and Deal with the data as it arrives and that means you can deal with the first result before dealing with the rest And there's a real there's a huge performance benefit to this So here I've got an example of that. I'm going to throttle the network down to 2g There we go. So a regular fetch of this Jason Will take Depends on the connectivity, but it'll take around about Okay, so it's all about five seconds and because with regular Jason it has to download the whole thing before it gives you any of it So the first bit of Jason arrives after five seconds and so does the second but with a streaming solution It are getting the last bit of data is going to take roughly the same amount of time Yeah, so sort of five seconds, but we get that first bit after 364 milliseconds So there's a huge benefit here for slower connections. We can start showing results before we've received the entire the entire file So you might be wondering how I can use this to speed up my my Wikipedia demo Well, I can't because although you can use fetch to read a response in little chunks JavaScript has no access to the streaming HTML parser It might look like here I'm sort of happily adding HTML into an element but plus equals is the same as getting then setting So you're asking the browser to serialize a DOM and then you're asking it to parse some more DOM Like you've added some more to the end This is a performance disaster don't do this because the elements at the start of your string get created like hundreds of times I'm hoping we can get like a streaming HTML parser document fragment or something in future, but it's it's not there yet But in Chrome beta and Chrome canary we have we can create your own readable streams now This is something that's also being developed in in other browsers, too it looks like this you just pass in an object with these methods and It's also we want to create a stream of random numbers. We're gonna store an interval I'll show you why in a moment I'm gonna create a stream and I'm gonna pass in a start method. This is called straight away So in here, I'm gonna set up an interval that pushes a random number to the stream every second They control has other methods as well such as like closed to signal the end of the stream But we're not using that here. I'm also gonna add a cancel method This is when the user cancels a stream after they're done reading it you get this cancel method So I can use this to abort the the interval So this is just like fetch streams now. I'll show you an example of that running I think it's this one. So yeah, here we go So this is just the code you saw before but I'm going to read the value three times and then cancel and then try and read it again But what we'll see if the page loads should be great. You can see this log down at the bottom here It's getting those numbers. It gets three of them, but then it's had enough of it So this is a this is a push-based stream because we're pushing data into it So if no one's reading from the stream, those numbers are gonna build up and up in memory and eventually you'll get memory problems The opposite of this is a pull stream The pull method is called when a reader is waiting on a value and we don't have anything left in the buffer So when pull is called I'm going to return a promise that waits for a second And then pushes the random number on and this is much better because you're not generating random numbers if nothing's waiting for them Your streams can be of anything that we fetch we saw there are you in state array of bytes here It's numbers. It could also be objects It's just one interface for all of those things the designers of web streams They talked a lot to to the node folks because they have they've had like four three or four versions of streams And they've they've made mistakes along the way. So there's a really good source of like well What did you do wrong so we can avoid making the same mistakes? So you might be wondering how I can use this to speed up my Wikipedia demo Well, I can't Because not just using streams on their own anyway because things get much more interesting when they're combined with a service worker So this this already streams Fine, it just does it automatically the browser connects the dots same with this the browser will stream it from disk from the cache But in cron beta and cron canary you can create responses from streams. You can create your own streams And then stream those into the browser So my fetch event I'm gonna create an encoder So this is the opposite of before it takes a string and turns it into bytes because response streams must be bytes We saw that before then I'm going to create a stream with a pull method Which waits a second and then pushes a paragraph onto the page So you can see that I've got encoded on code to turn it into into bytes And then I create a response give it the stream and then say that this is HTML give it the HTML header So if we run that it should be here We can see random numbers appearing on a one-second interval So but as far as the browser is concerned It is just receiving text very slowly and you can see that the spinner at the top there It's as far as the browsers where it is just loading a page very slowly so you might be wondering How I can use this to speed up my Wikipedia demo. Well, I can I actually can this time Before we were piping content, you know straight into the the browser streaming HTML parser and that is the key to it all here You know, this is what app cache wouldn't let us anywhere near So instead of turning like a perfectly capable server rendered sites into a JavaScript driven single page web app I can use service worker more like my server So here's what I did for a wiki offline. I fetched the article header the body and the footer So the header and the footer are coming from the cache the body is coming from the network But it will fall back to the something in the cache if it fails Then I combined those streams together into one single stream and combined as a function. I wrote it's about ten lines It's kind of a manual process right now It's like creates a single stream that reads the first stream into it then the second then the third and so on until It's ran out and then it ends and then we create a new response using that stream So one response made of multiple different parts and places Just like you do on the server you get some stuff from a database some stuff from a template Etc etc treating your service worker to a server maps really well to content sites like blogs and Wikipedia which a server driven See the result of this for one final time. We go back to the compare Oh the sound this time great You'd normally be bored of that sound by now, but that was the first time So here's how it compares so on the left the app shell render and on the right the streaming service worker Both over 3g so launch them at the same time So the difference is absolutely massive, but the app shell was a performance regression anyway So let's compare it to the original server render So we get the benefit of that quick cached first render which happens without the network But that allows us to get network stuff on screen quicker because there's less to fetch We've already sent the header and stuff down. I'll play it again So the first render is almost like a second faster But content render is half a second faster even though it's just coming from the network the same network in each example So needless to say I'm quite excited about streams But that doesn't mean the app shell model is bad You saw it being used if emoji earlier and the result was a progressive web app which launched faster than the native app But a streaming solution will be faster and easier for you if you use server rendering say like switching to an app shell model Here could be a lot of work and could land you if a performance regression if you're already a single page web app You have that performance regression already. So knock yourselves out carry on doing that Consider streams if your initial content may come from the network And the benefit of streams is being able to build content from multiple sources If your initial content comes from the cache or a database entirely then you don't have so much to gain from streams So that was the case with emoji I was getting all the first render content from caches and databases so streaming wasn't a whole lot of use there Consider streams if a partial content render is valuable to you and that I think is in most cases, but especially written content So if you're looking to build something like an offline first news sites like the Guardian or a shop like Amazon or your blog Streams could be the faster and easier way to do it and they're landing in Chrome in the next few weeks And they're being actively developed in Firefox and Edge If you want to know more I've written an article about streams Gushing praise on my blog in this post I do some sillier stuff as well like kind of transcode and an MPEG to a gif on the fly or or transform content I actually did this with the Iran a Transform stream on the Wikipedia page for cloud computing. This is it but every time it sees the word cloud It's replacing it with but Which is great to read. Where is that? I've got a favorite bit in here. See if I can find it There it is Oracle announced the Oracle but While aspects of the Oracle bus are still in development this bus offering is poised. I love the term but offering. That's great So service worker is this is Bruce Lawson's logo for service worker. I like it. It kind of makes me feel slightly drunk. It's great You can polyfill new network features with it You can become a faster network resilient more network resilient We've gone through a lot of stuff here at lightning speed and that monitor has gone off and I've got one slide left So let's rush There's also a free Udacity course where you can take a website from online only to offline first to use it over a series of Examples covers the app shell model and index DB and with that before everything just sets on fire and breaks Thank you very much. Cheers And now it's time for a break because I need one So we're gonna be back here half 11 for the next talk which is by Emily all about HTTPS. Thank you So Welcome to totally tips. This is an episode on dev tools We're going to talk about our newer progressive web app tooling Yeah, so the reason we have to do this to be recorded an entire video episode and then everything changed It's Tuesday. So dev tools has changed Right. So the resources panel has now been replaced by the shiny new application panel so I'm currently on progressive web app This is smaller pictures and some of the newer stuff that we we let you preview include like your web app manifest Yeah, so basically web app manifest is Kind of if you've ever built web apps So you've had to do icons for Different devices and browsers and you had to put in lots of link tags Manifest is Jason file where you can put all of that stuff in one separate resource and the browser will only go and grab it When it needs it. Yep So we summarize everything from like your name your short name through the different theme colors and background colors that you're using We show you your orientation chosen in your manifest file and then just like preview all the different icon sizes You might have set up. So I've got like all of them because I'm crazy. You are crazy I'm crazy. It also lets you emulate as a home screen if you click on this little link here That's just like the experience where it'll show you. Okay. Well, what do you want to name this thing? So the reason this is important is because whenever you click on add to home screen What it will do is it will go through all of the criteria that chrome looks for To basically decide whether it's going to show the user the banner or not So it'll be things like does the web app have a service worker? Does it have a short name does it have theme color? And if any of those criteria aren't met it will print out an error to the console just saying yep You need to have this and because it's not there. I can't do at home screen Cool. So the next thing we're gonna take a look at is the service worker panel So debugging service worker has been like historically really really painful And I think DevTools has nicely evolved over time to make that experience a little bit sweeter Yeah, this is definitely like the best version of it It's it's just really hard when you're starting out to understand what is going on when you're doing this stuff for the first time But I think there's definitely like the nicest version so far Yeah, so we're gonna gonna quickly walk through all the options here So the first one is an offline checkbox and basically if we go and we refresh you'll see that what the app is working offline This just emulates offline in the same way that the network throttling drop down. We'll let you do noise Fairly useful when you're testing offline support with service worker The next option is update on reload which forces your service worker script to update on refresh So the reason this is a super handy is Before this existed what you'd have to do is you'd make an edit to your service worker You'd save it you'd go back into your browser you'd refresh and once you've refreshed the page It will still be using the old service worker because your new service worker will be grabbed by the browser it will go through an install stair and The new service worker can't take over the page until the old one's gone So when you check update on reload what it's doing is it will unregister the old service worker register the new one And once the new one's ready to go it will refresh the page so then the page is using the new service worker So it's one checkbox. There's kind of a lot of stuff going on behind the scenes and it's super useful Next up we've got bypass from network which will bypass your service worker script and load resources from the network The reason this is handy is when you're not working on a service worker and you're working on other files You don't want anything to be poured from the cache. You just want to be using the files that you've just changed Then we've got show all and show all would basically show you every single service worker. That's registered Because we've got like an increasing number of sites and apps using this you might find this a little bit noisy I just say you're very unlikely to ever want this until something like foreign service workers come in But yeah, we're just we're just letting you know that it exists today Unless they change it tomorrow, but it's it's here today at least what else does this let you do? Okay, so you can update your service worker. There's a push Option as well. What does that do? Let's let's head over to your demo. I'm gonna guess it's gonna do something with push messages Yes, you're so bright path. Yeah, right. So this is a push demo Matt wrote a while back We're gonna go and we're gonna enable push notifications and your demo worked this time. Yes, right? So what we're gonna do is if we click push, it's gonna emulate a push event You'll see that we get push notification This is kind of interesting because this is the first time I've actually Seen or like tested this myself in canary and they basically added a new feature where it's it's populating a little bit of data in there Which is kind of super interesting Slightly weird with the fact that you can't determine what the data is But it's awesome that it's there because it does mean that if you wanted to check what data would look like when it comes In your service worker, you know, it's now something's there. It's awesome sweet What happens if we click send a push via xhr does anything happen? It should do it should do did I actually oh, I didn't there we go I don't know you did a GCM. Just took a while to kick in. Okay, so there because there's no data It's just like a super generic. Hey, thanks for sending this message sweet you can also go and click on the Little name. Oh, you've got a minified service worker. Yeah, man. What would eat? Okay, let's let's go to someone who hasn't done that and if we click on source you can go and you can check out the He just doesn't care about users data So the reason this is actually super cool Is the fact that you can now have breakpoints to your service worker like you would any normal JavaScript files So when that code gets executed in the service worker It will actually stop the service worker from running and you can start debugging stuff like you normally would with DevTools Which is noise sweet. You can also so you can see that we've got like these activity indicators for the status So green means that something is active and it's running You can stop your service workers. We can go and do that. They'll say activate and stopped you can focus your clients So we're currently focused and also hit details and I'll show you in line any of the exceptions or error masters You've been getting so the one thing that used to exist here that's been removed You should be able to have like an inspect button that you would click and it would open up an entirely different DevTools Just for service worker. I still kind of like having the two DevTools one for the page of service worker but I think the DevTools team are trying to Get everyone to work just out of the one DevTools and change different context So in this case all the service worker logs would show up in the one console and you select different Frames within that so it's kind of interesting. This is the only thing that I'm Anxious about I guess But this is quite a nice way of at least servicing just the errors because I'm a DD I'm just going to click clear and now all of our problems have gone if only life was that simple Clear storage is basically the best thing ever if you're developing any non trivial progressive web app And you know you're trying to support offline with service workers You're maybe using you know storage mechanism like index DB your local storage or session storage You've probably run into the situation where you know You need to manually go in and clear all of your different storage mechanisms out and then head to different panels to unregister service workers And it's just it's this whole super tedious thing Yeah, I've ended up writing helper scripts that I just drop it to the console to delete everything. It's Yeah, it's annoying when you get to that point. So in an effort to make Matt Gaunt's redundants There's now like a clear sight. Well, I escalated quickly There's now a clear site data button I think the label for this might might be changing this the button is still there Basically what this does is it almost resets the world for you, which is kind of really nice It does all the things it says above like it will unregister your service workers in your storage and clear out your cache API storage and Yeah, this does seem like an obvious feature But at the same time it hasn't existed for the longest time and when you start working with service workers You realize how quickly you just get into a mess and you just want to Reset everything and the old solution for that was to just develop an incognito windows. So this is super welcome This is this is so nice. We were talking about cache storage because this is this is was resources panel You can still go in and debug all of your different storage mechanisms that includes the cache API So in the case of my app, I'm using SW pre-cache. So I've all these entries for someone like Paul loose his voice memos app we go in here and you'll just see that there's like there's an entry that's got all the different Files listed that he's got cached in the cache API. I wonder why the response is empty. It's all it's all perfect It's all perfectly perfect And you've also got other options in here like frames Don't just say that like it is no one knows what frames is I don't know what this does anymore It's it's basically a breakdown of different things for a list of assets that's that's let's assume that it does that Maybe maybe this gives us something to do another episode on next week on Totally totally many tips. What is frames under applications tab? All right? So I feel I feel enlightened. That is that is the application tab. Is there anything we're forgetting? You've got device art on the screen shot So canary DevTools now lets you like preview device art for for a few different devices We've got the Nexus 5x in there I think the six might also have device art it does not it does in the very very latest version I think so it's coming. I think it's coming But basically device art is awesome Just lets you like see what it would maybe look like on an actual device and it adds in like the navigation bar at the top And yeah, you can go in you can go in here and like get your little navigation bar in I have asked for us to like take the theme color into account. Oh, yeah, you could you could do that. Yeah Yeah, that'd be really nice, and then it'll yeah assume that by the time you've seen this Maybe we've convinced them and this is already out to date and if not raise issues and maybe we can get it All right, so that that is the application tab Hopefully you'll find that a lot of this stuff makes it a lot easier to develop and debug your progressive web apps That's it from us. Thanks for listening. Bye Welcome to this supercharged tldw. I'm Paul if you didn't catch the live stream with me and Serma last week Well, basically we built a side nav. Let me show you what we built. So you've got your standard app bar here and click on this Sidebar and you click on the background or you can dismiss it with a sort of drag gesture like that awesome stuff So let me show you how we built it But before we do that as usual we're gonna head over to yep, you guessed it theory corner join me Hello, welcome back to theory corner. So this is what we've got We've got our page and we've got a container element The container element is going to be the home for the side nav and the background What I'm gonna do first of all is gonna put overflow hidden on this We're gonna make it take up a hundred percent width and height So it's got overflow hidden because this is gonna transform out to the side and we don't want any scroll bars So we put that in place The background we're just gonna transition its opacity from zero up to one and we'll set it to have a transparent black color Or semi-transparent black color in the background. The other thing is this side nav We want this to slide in from the side So we need to have will change transform on it so that it gets its own layer very much like we did with the Swipeable cards and then we can transform it in and out. We're also gonna need some Buttons for bringing it in and out. We're gonna have to have some touch events so that we can do the dragging stuff All cool. Let's go back to Reality Welcome back to reality. Oh, yes. Yes reality. That's where you'll find us today pragmatic to the end code Okay, so the markup and the CSS is pretty much what we discussed in theory corner We've gotten aside. We've got a few JS classes here so that we can pick it up in the JavaScript But mostly it's pretty much what you'd expect. There's a button for closing. There's a button for opening We've got a title here for the side nav and then we've got the list of the side nav content in Terms of the CSS. Here's what we've got for the background You see it's actually done with a before pseudo element and you can see that it's got a background of black with an opacity of 0.4 We switched on will change opacity because we know we're gonna be changing the opacity. So we're gonna say will change opacity Didn't say will change pasty That would be a different thing entirely Will change opacity and then we can set a transition of opacity with that curve That looks quite nice 0.3 seconds nice and quick Then the other thing is when we set the side nav to visible which we're gonna do with some JavaScript And we can say to that before that we want you to fade up from an opacity of zero to an opacity of one The same is pretty much true of the side nav itself Here it is and you see it's got a box shadows We got a nice little bit of shadow on the side the interesting thing is we have to transform it by in my case 102% which sounds really odd But the reason is there's that shadow and if you just transform it 100% to the left You still see a little bit of shadow on the left-hand side So we just take it a little bit further solves that problem The interesting thing about the side nav itself the one that comes in from the side is that it has a separate Animatable class the reason is I want to switch that off when they're doing the drag motion and have it on when they're doing the Automated transition from the side in and out so we use this class to basically say this is kind of it's doing the automatic Transition or when it's off is going to be used for the dragging cool the JavaScript is over here and It's the same trick as last time a bunch of event handlers that we bind on with this If you haven't seen why I do that go back and watch the swipeable cars TLDW explain pretty much Why I do this approach to my event handlers you don't have to take this approach, but it works pretty well for what I'm doing So we bind all those on and you can see here. We've got the show and the hide now Here's an interesting one I actually say that if you click on the side nav the containing element the container from theory corner I want you to hide the side nav. Well, that will work Kinda, but then if you click on something inside the side nav Well, that's kind of weird because you click on something inside of it's going to dismiss The way we get around that is we basically say the side of itself that's going to hide it But any clicks inside we're going to Call this block clicks function, which you can find down here and block clicks all that does is stops the propagation So it's almost like cancelling the event now You don't want to do this all the time you only want to do it when it makes sense for your app and it makes sense in my case I think so that's all good. So I think all that's really left is just have a quick look at that drag motion Now if you remember the drag motion looks like this We can click and we can drag and if we just come away from the side a little bit and let go it dismisses the side nav So let's see how we code that in Well, we have our on touch start here and basically because this is bound to the document I basically say if the side nav isn't open Bail don't hang around so we we we're going to call this any time so many hits touch start But we only want to deal with this if the side nav happens to be open And what we do very much the same kind of deal as the swiper ball cards We capture the start position and we copy that across to a current position and then in the touch move We basically figure out how far we moved and then we can apply a transform in a kind of game loop and update function Which you can see here There's the translate current minus start and then we apply it as a transform if you see in swiping all cars This is all sounding very familiar I'm sure but it works and it works really well the last thing is on touch end We basically say if you've translated just a little bit to the left hide the side nav that works out really well for us One other little thing to note is this In terms of the on touch move by default you'll get that throttled back in chrome So you won't get them every frame unless the very first touch move event has an event dot prevent default on it So what we do is we calculate the translate and we say if it's less than zero as in you've started to move it We prevent the default and that means it will get all the updates from then on so there you have it That's the side nav pretty straightforward in terms of these things, but this works really well It works at 60 frames a second even on a mobile device if you haven't caught the live stream against about an hour long It's in the description below So have a look through there and have a watch of that if you've got a spare out again It's usual kind of stuff. You see all the bugs. You see all the chat You see all the discoveries and the kind of discussion that Serma and I had don't forget to subscribe Done and I'll catch you next time if you like me like clicking on things you can Hey folks welcome to totally tooling tips season 3 come check us out We're gonna be talking about progressive web apps some of the tooling around them on first visit We've got a relatively fast time to first meaningful paint module bundling accessibility Do you know what the top four things to look out when it comes to web accessibility are? No, I can anything of two light anything of audio and then visual so there's visual hearing Mobility and cognition the first episode will be out on April the 27th So subscribe to YouTube channel check out season 1 and 2 before season 3 starts to be happening soon We promise that season 3 is going to be equally as mediocre at seasons 1 and 2 Chrome 51 makes it easy to know when an element enters or exits the viewport with intersection observers You can make the sign-in process way easier with the new credential management API and You can reduce jank with passive event listeners. I'm Pete LePage Let's dive in and see what's new for developers in Chrome 51 Intersection observers let you know when an observed element enters or exits the browser's viewport No more jank inducing calls to get bounding client wrecked or listening for scroll events to use Simply create a new intersection observer Provide a callback and an options object Then tell the observer which elements to watch Boom when the element enters or exits the viewport the callback is fired Check the description below for a link to a demo browser support and more creating remembering and typing passwords is a pain in the Neck especially on mobile Chrome 51 supports the credential management API a new W3C spec that allows your site to interact with the browser's credential manager and Federated account services like Google and Facebook improving the login experience The API has three key methods Navigator credentials dot get to get the user's credentials and initiate a sign-in flow store to save the user's credentials in the credential manager and Require user mediation to disable Welcome back. Thanks for playing my personal theme music Hi, everyone. My name is Emily Schechter I'm a product manager on the Chrome security team and today I would like to take you on a myth-busting journey about the protocol we use to send and receive data on the web over a secure connection and That's HTTPS and I think this is one of the most important topics for a web developer today So our story begins on a dark creepy night in 2010 Imagine that in 2010 you're sitting at your computer. You're serving the web. You're getting sucked into a YouTube hole You're watching the Twilight Saga trailer or maybe that double Rambo video or one of the other popular YouTube videos in 2010 You fall into a deep sleep so deep that you don't wake up until today until 2016 and You look around at the web today and it looks pretty different from the way things were in 2010, right? Today we have things like add to home screen which lets sites behave more like apps and we have push notifications Which help you keep engaged with your users keep them coming back And we have cool new API is like device orientation and geolocation All these cool things around today that let you build progressive web applications That let sites do all of the cool things today that they really couldn't have done in the past So these things are very powerful features, but there are also a lot of responsibility, right? Take geolocation as an example If a site knows where I am it also knows where I work Where I live where my friends live Maybe where my children go to school where my doctor is That's a lot of stuff for a site to know about me, right? So if you woke up in 2010 to find this very powerful web You might be surprised to learn that there are still websites out there where you can make a purchase with your credit card or send a private message to a friend or Research a sensitive medical condition in such a way that an attacker ease dropping on the network Can see all the data that you're sending back and forth Or you might be surprised to learn that there are still websites out there that spend tons of money and time and energy crafting the perfect user experience Only to deliver that perfect user experience and have some ISP or Wi-Fi provider or some other intermediary Inject really ugly obnoxious ads like this and this isn't a hypothetical We actually see major ISPs doing this ad injection all the time And if this was your site, you'd probably be pretty upset, right? Because this interferes with that perfect user experience It might be disrupting your revenue streams by blocking your own nice ads and Worse it might actually trick your users to downloading and installing malware on their computers So if you woke up in 2016 You might hope to wake up to a web where data is protected from this kind of snooping and tampering from the very beginning And that's what we get with HTTPS That's what this green lock signifies and in 2016 We're hoping to move towards a web Where this green lock is so ubiquitous that we might not even need to show it at all because it's just the bare minimum security That we've come to expect for any site on the web today So this green lock Signifies three main security properties First identity When you type HTTPS google.com into your browser Your browser receives a cryptographic proof of identity called a certificate from the server and The browser uses that certificate to prove that it's talking to the real google.com Not some other fake site who's pretending to be google.com So when you type a URL into your address bar The browser gets a proof that that's the real domain you're talking to Next confidentiality Once your browser knows that you're talking to the real google.com Both those parties the browser and the server have a guarantee that only they can read the data That's being passed between them and Not over any other friendly person eavesdropping on the network and Finally integrity The browser and the server have a guarantee under HTTPS that when they send data from one to the other The data they see is what the other party receives So an intermediary in the network Can't modify or tamper with the data that's being sent only the browser and the server can and That's what we get from HTTPS But you might also have some other associations in your mind with HTTPS When you see this green lock you may think that it represents a financial burden or a performance cost or a lot of maintenance or it's really difficult to set up and Many of these associations actually were true 10 or 15 years ago, but many of them are no longer true today And that's because people all over the world and all throughout the web ecosystem Have been interested in promoting a safe future for the web where HTTPS is everywhere So in this talk what I'm going to do is tell you four stories about HTTPS Try to separate fact from fiction Show you what might used to have been true in the past But is now becoming a bit of an HTTPS myth and Try to convince you that HTTPS is both possible and important for every site on the web today so my first story is about a web developer named Alice and Alice runs an online travel guide. You can see it here. It's a very cool awesome travel guide But it doesn't have any privacy or security sensitive content. Like it doesn't have a login page You can't make any payment transactions And so Alice doesn't think of her site as something that would require HTTPS But one day Alice is talking to her friend And her friend says that on her computer Alice's travel guide is really slow and sluggish And Alice is like, okay, that's weird because on my computer. It's really fast and snappy, right? Because that's the way I built it to be So she goes to her friend's house and she checks out what's going on And you can probably guess what's happening. She sees a bunch of terrible slow ads plastered all over her site So this is ruining the experience that Alice has built it covers up her own lightweight unobtrusive ads and Alice's friend trusts Alice's site So she clicked on these ads and when she did she didn't expect to get the malware that she downloaded onto her computer and This is natural, right? A user who sees terrible ads on a site Blames the site for that terrible experience So Alice is pretty sad about this as you would be I'm sure and to console herself She starts working on a new feature and let's say this new feature is using the HTML geolocation API To suggest fun travel stuff to do based on this user's location But as she goes to implement this feature she goes to try it out in Chrome and she sees that it doesn't work and The reason that it doesn't work as you can see in this error message in the developer console is That Chrome and other browsers are starting to remove support for powerful features like geolocation when they can't be safely used over non-secure HTTP So in order to use the geolocation API your site needs to use HTTPS and There's a good reason for this, right? If I'm going to trust Alice's site with my location I need to know that I'm talking to the real Alice's site not some other site pretending to be Alice's site So we need that identity property of HTTPS to be sure That when I grant a site access to my location, I'm actually talking to the site that I trust with my location So Chrome and other browsers as I said are not limiting this to geolocation There's a list of features that have already been removed when accessed over non-secure HTTP And there are a few more that are coming down the pipeline. I want to call out app cache specifically Which is coming up next and longer term EME We actually don't have specific public timelines for these yet But they are coming up next and we'll be sure to be responsible when announcing timelines We'll add a notification and Chrome dev console But if you are relying on app cache or EME over non-secure HTTP We encourage you to start thinking about HTTPS now before it becomes in emergency So what about service workers? Service workers are amazing as you've been hearing today My love for them is represented here by these sort of bizarre blobby Android heart eyes emoji They're the super. They're the secret superheroes behind progressive web apps that enable performance in the face of sketchy network conditions Service workers sit between the browser and the network. So they actually manage every request that comes through And as you can imagine Alice as a site owner Needs confidence that she is the one managing those requests They're not being controlled by some other Super-friendly person on the network trying to enhance your browsing experience and this is why service workers require HTTPS So Alice realizes after all that that in order to build a progressive web app with the features that she wants and In orange to guarantee that the user experience she builds is the one her users receive She needs to use HTTPS And this is why we think that it's important for every site on the web today to use HTTPS Even if the site doesn't seem immediately privacy or security sensitive So this story is fiction. So our next story is about performance and a data-driven guy named Bob Who's done some careful testing some a b tests and he has found that reducing latency Reducing the time it takes for a user to load a site is crucial for optimizing conversions on his site so the faster his page loads the more money he makes and Bob has heard some not-so-nice things about HTTPS and performance yell.com is an online business directory that recently made the switch to HTTPS and They recently publish a blog post describing their move to HTTPS and What's interesting is that they did experience some negative performance results And on the other hand Google moved Gmail to HTTPS way back in 2010 with basically a negligible performance impact So Bob is wondering what's going on here. What's sort of the discrepancy between these two stories? So let's dig into some of the reasons for this discrepancy and try to figure out how you can move your site to HTTPS Without a performance hit So first let's look at a simplified view of what it might take to send in HTTPS requests And here I'm highlighting some of the network latency Imposed by the extra round trips between the browser and the server created by using HTTPS on your site so first There's an HTTPS redirect If you follow a link to an HTTPS page the server says actually that's moved to the HTTPS version next The browser and the server do what's called a TLS handshake Where the server presents that cryptographic proof of identity, which is called a certificate and That sets up the HTTPS connection and Finally the HTTP request is made So it turns out that if you dig into what it takes to communicate over HTTPS There are some technical optimizations that you can do to reduce latency So let's step through this again and see what we can do to optimize at each step So first There's that initial HTTP redirect to the HTTPS site strict transport security or HSTs is an HTTP header that helps you avoid redirects from inbound HTTP links to your site by telling the browser Only access my site over HTTPS for some period of time And you can set this period of time yourself and you are committing to supporting HTTPS for that period of time and So HSTS helps improve performance by avoiding that redirect round trip So the next two round trips are used to set up the secure connection Over which the browser will send the HTTPS request And this is known as a TLS handshake So let me interject here for a moment to tell you that as a product manager and an all-around friendly person I shake a lot of people's hands and there are some really terrible handshakes out there First there's kind of that bone crusher handshake which just cuts off all circulation to your fingers Right, and then there's like the sweaty palm which is just brutal There's kind of the dead fish which honestly just makes me depressed But the worst kind of handshake It's the person who grasps your hand and kind of shakes it and then just looks at you and Continues shaking and keeps looking at you and keeps shaking and shaking Because it's just incredibly awkward and it just takes such a long time So the moral of this story is you have to make your handshake as short as possible to get on to the really interesting part of the conversation So normally the browser and the server are doing one of these long terrible handshakes And the browser is waiting for this TLS handshake to be completed before it sends the HTTPS request But this is actually not necessary You can actually remove handshake latency by sending the HTTPS request in the middle of the TLS handshake So after the certificate is received from the server, but before the TLS handshake is completed so it will look like this and This is called TLS false start and You can turn it on in your server software and it removes a round trip from the handshake latency and If the browser and the server have spoken TLS before The browser can remember a session ID and The next time it goes to make a TLS connection It sends that session ID which allows the browser to shave off part of the TLS handshake and This is called TLS session resumption and it also allows you to shave off a round trip And if your server supports it, you should turn it off so now that we've talked about optimizing that first redirect and Optimizing some of the round trips in the handshake Let's talk about sending the actual HTTP request and This is where things really get cool Because this is where HTTPS unlocks some pretty dramatic performance improvements in the form of HTTP 2 This is the next version of HTTP which is now supported in many browsers including Chrome and Firefox and using HTTP 2 You can do really cool things like Multiplexing and server pushing which majorly optimize performance for HTTP requests and Serma is actually going to give an awesome talk on HTTP 2 that dives into these details right after this talk So please stick around for it if you're interested in more details So I mentioned that HTTPS unlocks the mouse of browser performance wins of HTTP 2 and What I mean by that is that Browsers have said they are only going to support HTTP 2 over HTTPS So if you want to use HTTP 2 you have to use HTTPS There's a practical reason for this and it's compatibility So there are some intermediaries like proxies that are likely to get kind of confused or in some cases actually break things if they see HTTP 2 traffic Because it just looks so different from normal HTTP 1 traffic. So we need the confidentiality guarantees of HTTPS To be able to support HTTP 2 without actually breaking anything So if we go back to yell comm that online business directory that Bob read about and was unhappy to see that they had negative performance impacts for moving to HTTPS It turns out that most of their performance impacts were mostly due to outdated load balancers But they couldn't update at the time and they couldn't actually turn on HTTP 2 But they're planning to upgrade to HTTP 2 in the future And we have hope for yell comm because of stories like weather comm Who saw a small performance impact from moving to HTTPS But it was then majorly blown out of the water by the subsequent performance wins of moving to HTTP 2 So in the end Since Bob is in a position where he can update his server software and turn on some of these optimizations He shouldn't see any performance impact from HTTPS And if he does he should be able to far outweigh it by moving to HTTP 2 So we have to update the way that we talk about HTTPS and performance HTTPS is now necessary for achieving the best the web can offer and HTTP is underperforming So how many of you work at startups? All right few awesome So my next story is about a startup that might be something like yours So Charlie has an idea It's about messaging with friends on the web and she raises a bunch of venture capital funding for it but these days Charlie startup is kind of running out of money and the VC market has gotten a little bit tighter So she needs to make sure that every dollar she's spending is going to a good cause and She's heard that HTTPS cost money Maybe money that she can't afford Now money is sort of part of all of these stories in some way or another I talked about performance which kind of boils down to money and Next I'll talk about ad networks, which is about money But in this story, I'm going to focus on two aspects that Charlie is particularly concerned about Those are certificates and search ranking So first these cryptographic proofs of identity certificates When you need to get a certificate Traditionally you buy it from an organization called a certificate authority You prove your identification to the certificate authority and it gives you a certificate that you use to prove your identity to browsers You ain't wonder how much these certificates cost Well, it's certainly possible to pay a lot of money for certificates You certainly don't have to a Project called SSL mate has for many years now been offering standard SSL certificates at 16 bucks a pop And you can also get one of their more advanced options multi-host SSL Multiple certificates, and even if you need one of these it really shouldn't break the bank And there's a newer project called the let's encrypt which actually offers free certificates and Both of these projects SSL mate and let's encrypt offer automated command line tools that help you buy and manage your certificates Automatically so they don't expire You can set up configurations other tasks like that So certificates are not going to be the reason that Charlie startup runs out of money The other thing that Charlie's work Charlie's worried about is search ranking You can imagine that if you move your site to HTTPS Search engines might get kind of confused And you might lose search ranking because kind of a traditional negative wisdom is that having two different versions of your site Can have a negative impact on search ranking So Google in particular has a few best practices that you should follow when moving your site and here I'm going to talk about the basics So the first thing you should do is serve 301 redirects to show search engines that your site is at the HTTPS version and Once the search crawler gets to the HTTPS site It's important to serve these canonical link elements to reinforce the idea that this is the canonical version of your site and There are a few other best practices that you should follow Three up here, and I encourage you to go check out these resources after the talk So if you do your research and follow these best practices You can expect a minor fluctuation in search ranking which happens any time you make large changes to your site But you'll then recover back to your normal levels that you had before the transition In fact Google even does have a search ranking boost for HTTPS sites So it's actually considered a positive ranking signal at present It is pretty small. So you probably won't notice a large boost But it's possible. We're hoping that might change in the future and it is a small positive signal now So in other words if you follow best practices take a little time to do research before moving your site over The financial costs for certificates and search rankings should be negligible so my final story about HTTPS is The story of Francisco and his adventures with third-party content I'm sure that many of you have lots of third-party dependencies on your site So let's say that Francisco runs the website for a major news corporation And that means he has a large site with a lot of articles a lot of legacy content Many different types of third-party content to worry about like old images And he's heard that if you move to HTTPS All of your content including the third-party content also has to be served over HTTPS So it's easy to see why this might freak Francisco out a little bit because it's true that when you move to HTTPS You're going to also have to start to think about whether all your third-party content is available over HTTPS First and foremost Francisco is worried about ads because he runs a publisher site and ads is how he makes all of his money So Francisco is wondering whether his ads will be available over HTTPS Well something that has changed in the last year or so is that for Google addicts ad sense and ad exchange requests They're always served over HTTPS for most users So even before Francisco has served his site over HTTPS His ad exchange or ad sense ads are already being served over HTTPS for most users so he shouldn't have to worry about this and The exception here why I'm saying most users is actually only for users located in countries that actually block or degrade HTTPS traffic And this isn't just a Google thing it's actually an industry-wide trend in 2013 the IAB the interactive advertising Bureau published this blog post Saying that nearly 80% of their member advertising systems support HTTPS And they underscored their commitment to getting all the way there to a hundred percent So this is one of those things that I talked about where five or ten or fifteen years ago Pretty much no ads were being served over HTTPS So this was a major issue But now the entire industry is changing and in this day and age serving ads over HTTPS Really shouldn't be a blocker And if you're using an ad system that doesn't support HTTPS yet It's probably on the roadmap and if it isn't you should ask them why not and you should tell them I said why not So the next type of third-party content that Francisco is worried about is the partnerships that he has with other sites that depend on the HTTP refer header And what this means is that other sites can tell that the traffic came from Francisco site In other words Francisco site has referred the traffic to those other sites so Francisco might get some money for this and The problem here is that if a user follows a link from an HTTPS site to an HTTP partner site browsers will strip their refer header for privacy reasons and That makes sense because if you're doing something sensitive on an HTTPS site The URL that you're on might be sensitive information and the browser shouldn't just leak that in plain text over the network to an HTTP site Fortunately, there's a web platform feature called refer policy that helps with this and Francisco can set a refer policy to allow his partners to see that traffic is coming from his site But they won't see the full URL that the user was visiting so user privacy is still somewhat protected Finally Francisco is losing sleep over a kind of general problem called mixed content and Mixed content is the problem of loading non secure HTTPS content on an HTTPS site and This is important because non secure sub resources can actually compromise a security of a secure HTTPS So if you try to load in secure scripts or iframes or other active content like that on an HTTPS site Browsers will actually block it because that content is just too powerful and would completely wipe out all the security of that HTTPS site So Francisco site It's a news publisher So it has lots of old news articles that link to third-party images that aren't available over HTTPS And we call these images passive content and Browsers will still allow them to load so the site won't be completely broken, but that green lock does go away and Francisco is really not happy with this because he wants his green lock that he worked hard for Fortunately Francisco can serve what's called a content security policy to receive reports about mixed content This header is basically a way for Francisco to assert to the browser that all content should be loaded over HTTPS And he wants to receive reports about any content that isn't and That allows him to go find and fix mixed content on all of his millions and pages Which means that he doesn't have to rely on users to report broken behavior He'll be able to find and fix problems as soon as they arise So in this in this case the CSP says all content should be loaded with the HTTPS scheme But in line and dynamically generated scripts are okay and Send a report to this URL whenever content violates this policy But don't block content only report it And if you don't want to build infrastructure to collect reports yourself I suggest this awesome service called the report uri.io Which gives you some cool data visualizations And for all of these issues in Chrome We recently launched the dev tool security panel to make it as easy as possible to find and fix problems with HTTPS configurations such as these mixed content problems So Francisco's story is true in that third-party providers must support HTTPS in order for you to move your site over But what's new what's changed in the past few years is all of these new tools and support in the ecosystem and In the web platform to help you upgrade your third-party content So when I look back at these four stories about HTTPS that I told you today I Think there's one kind of moral that emerges And that moral is that five ten or fifteen years ago HTTPS used to be kind of slow Kind of expensive kind of a pain set up But these days in 2016 browser vendors web developers like yourselves server software developers Security researchers the whole wild wild west of the online advertising ecosystem All of these people have come together to make HTTPS a lot faster and Easier and cheaper and all-around better than it was in the past and HTTPS is necessary for unlocking the best the web has to offer in terms of both capabilities and performance And that's why we think it's both possible and really important for every site on the powerful web today to use HTTPS So thank you so much for listening if you have any questions come find me after either in the co-lab area or in office hours tomorrow and Next up Serma will be giving an awesome talk about HTTP to which is unlocked by HTTPS. So welcome Serma Hello everybody I'm actually really relieved that I can be here on stage because a few days ago it didn't look like I would be here I had like this massively Thor's throat and Didn't have any voice left which what you kind of need when you want to be on stage so I went to the doctor the next day and He did the whole wooden spatula flashlight thing looked and then he said. Oh, yeah, I see it But I was like what and then he grabbed a pair of pliers went into my mouth and pulled out like an inch of Bamboo fiber is splintered. I apparently swallowed and it's just lodged in the back of my throat and five minutes later Everything was fine again. My throat was normal. My voice was back and I thought great Then I flew here and caught a cold on the flight. I guess that is bad luck Also, if you're wondering if that story had anything to do with my talk it absolutely didn't So my name is Serma. I work with the Google Chrome team in London And I'm here to talk to you about instant loading and how hv2 ties into that whole story So instant loading you probably know the experience you have something on the home screen of your phone You tap that icon and you expect the app to be there instantly to open up and to be ready for you to work with That is something that shouldn't have any white screens or spinners ideally So you just want to be the app should be there right away for you to work with and I'm here to talk about how we can achieve that With your web apps And it's actually pretty easy. You take a service worker. You slam it onto your web app You make it cash everything offline enjoy your instantly loading app done end of talk. See you later Obviously my talk is supposed to be a little bit longer. So there was more of a setup However, that advice is technically correct. You can't load much faster than loading from local cash with a service worker However, how do you get all your things into the cash that the service worker uses? And with the web apps that involves the network because you have to download them into the cash And then you have new bottlenecks you have the network and you have latency and all these kind of things And what do you do when some of the assets have to be updated individually? And this talk I want to talk about these kind of questions I will not even cover service worker because there's so much that you can do Before service worker actually get into the whole equation because on the first load the service worker is not there And on the first load that is your first impression. So you have to get that right too. So let's rewind rewind a bit Yes, we want to achieve instant loading, but that includes the first load as well And with the web that involves the network and downloading with ATVT before the service worker is there To a certain degree all the optimizations that we're going to talk about Also benefit the service worker because Loading from cash is kind of similar and however the impact will be a little bit smaller So I will talk Sorry I'll focus on the first load because that scenario is the worst case on the web You have nothing there locally. So you have to get everything from the web if you have something cashed For that resource you already removed one of the biggest biggest bottlenecks that is the network The overarching theme as you will realize of this talk is keep your assets small If your markup is small, it will be it will go faster over the wire The pauser has less to do and it will be done sooner same goes for JavaScript same goes for style sheets So just keep all your assets as small as possible Once we have that then we can actually look at the remaining optimizations in the instant loading problem space so to speak And as I said, I'm going to tackle this entire thing without even talking about service worker We're going to look at the features of the web platform as well as the HTTP protocol and if you don't know about the HTTP protocol All too much good news is we just launched a new Udacity course today And if you want to sign up first just go to the URL that is on the slide right now You can sign up and we're going to start from zero and take you all up to the all modern things of 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'll listen for this dude's Loading property and I'm going to call my attributes just so I can differentiate them a little bit I'll call it like is loading, right? 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. I mean this this came in, you know, seriously though come on Yeah, so I think progressive enhancements are right for you to do here late when you first load a page Even on a browser that supports service worker that first load is going to happen before the service worker installs and activates So, you know you can Make you can make a site depend on service worker But you we designed it so you have to jump through hoops in order to do that and if you do jump through those hoops You know, I might try and find you and kill you because yeah, I'm true believer in the whole progressive enhancement thing Are you threatening bodily violence on a panel? 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? Well, the theory for this one is going to be a little more involved But that's fun When I get something like this from a designer or I do it myself I kind of watch it over and over and over again. It's a thrilling few minutes But it's a useful few minutes because it'll as you kind of watch something over and over again Your brain starts to notice the patterns And the patterns here are in this case. I think that thing is is getting bigger and it's moving. Yes There's the pink head a bit that's fading in but predominantly this is about a movement It's getting wider and taller and it's moving And therefore I would normally go wow that feels like a width height left and top moment Great, that's probably what I would animate except that that would be bad And the reason it would be bad is that in every browser you would trigger Layout with the purple chunk at the top there Paint And composite layout is basically where the browser says where is every element? It's basically a geometric process. Where is a remote element every element? What is its size and so on paint is where we fill in pixels and compositing is where we put the page back together All those layers now if you've got to do that for every single frame And you might have a reasonable size to DOM You're in trouble You don't want to be able to go on to have to do this work on every single frame chances of getting 60 frames a second slim to not You may have noticed that I use transforms an awful lot and the reason is their profile is different for An element that's got its own compositor layer Changing a transform is not going to trigger layout and it's not going to trigger paint It should only trigger compositing which is something that we can probably get done Comfortably at 60 frames a second. So this then changes the question to look like this. Can we do that effect? With transforms Can we remap this? Slow mo Can we do that with a transform? Well to me that looks like a scale And it looks like a translation. Cool. My approach is called flip. All right, so that's the first last invert and play Because there aren't enough acronyms, okay So i'm adding another one Cool But it's an extremely useful way to think about the animation what we want to do is we want to Essentially ask the question at runtime. Where is the element that i'm interacting with so we record its first position on screen And we do that with something like get bounding client rect Which is fun to say and has been around since ie4 Brilliant and it will tell you in relation to the viewport where this element is it's left It's height. It's top. It's right. It's bottom All the stuff that we need to know Now what we can do is we can actually snap the element in question out to its final position Now i'm doing this with a class but you could manipulate the styles. You could do whatever you need to do So now our our card is going to be in its last position like so and we can call get bounding client rect a second time So now we know where you were And now we know where you're going to be That's cool. That means we can start to kind of figure out our transforms that we might need dynamically Now there is a word of warning here going from first to last Is going to trigger styles and layouts and the reason it's going to trigger styles and layout Is because the second get bounding client rect came after some style mutation We said here's a new class for you or here's some style changes And then we asked for how wide and how high and where are you on screen and the browser goes I don't know you just moved everything Hang on let me go and figure it out and i'll come back with an answer and that's exactly what happens So you've got to bear in mind that those from this first class and you might be sitting there going hang on a minute I'm sure you said triggering layout was bad and I did But the key is here. We're not going to do it on every single frame There are two things we need to bear in mind one. We're going to do it once at the start as a setup cost Secondly, we have rail which is going to be our friend here bear in mind the user tapped on a card To get the animation therefore In rail terms they're here. We have a tenth of a second in which to respond We have a tenth of a second in which we can do some work And believe me a tenth of a second is actually quite a long time Especially when it comes to this kind of work. It's great. We should use it and we do So when it comes to rail and flip you can typically afford to do a single styles and layout pass Then seriously one, but that's cool. That's often enough and in terms of flip. That's a good setup time You'll still need it to complete in less than a hundred milliseconds So you kind of have to be aware of how big the dom is and if you're able to use Something like css containment to limit the scope of layout and paint. You should definitely do that and That's really useful. However We knew where we were that was first. We know where we are. That's last and now we can transform What we'll do is we'll just basically apply an inverse transform to take us back to here We can do that. So first minus left, you know, blah blah blah Do that with a scale Apply a transform that uses those values So at this point we've done first, last and invert And it's like this. So if I was to tap on the card ready, steady go There you go From a user's point of view nothing happened What's really happening is this going first last And then we're inverting And it feels like a lot of setup cost and it kind of is but it gives us a huge advantage because what we can do now Is switch on transition on transforms And remove that transform And our card will just go We didn't know where it was but the start we didn't hard code it We just said, where are you going? Where are you now? I'll figure out the transform and I'll apply it for you We've just managed to remap something that was with height left in top Which wouldn't have run at 60 frames a second do something that definitely will Hopefully all being well Caveats though because there's always those If you've got some scale changes that are being applied They something like text let's say you're you're doing something flip like when you've got something with text inside That might get squashed or stretched So you might need to move the content to a sibling element so that it's not affected and then just sort of faded in or something Like that bit of sleight of hand You might need to do that bit of gymnastics, but it's well worth it Like I said, the first to last does involve forcing styles and layouts. You have to be careful with that But this is what it looks like in reality. This is a, you know, a little kind of expanding collapsey card thing Which you know that's running on a nexus 5x and this screen doesn't make it look at like at 60 frames a second But it is And I can prove it because I've got timelines that show it and you can see it. I'll show you. It's great It's also responsive design friendly. Like I said, we're going to ask at runtime What the first position is and what the last position is we don't we don't hard code those values Which means the same animation on desktop looks like this Different position different sizes, but still the same stuff And this is what it looks like in timeline We'll zoom in again to the top bit and you see the dip at the start and you see those red markers That's dev tools telling you your frames per second dipped below the comfortable point of 60 But we know that that was the setup of flip. That was the first last name Which on a nexus 5x on this case was about 40 milliseconds After that that is a steady 60 frames a second afterwards tremendous cool, I get to Call this one a day in a moment Some closing thoughts You've noticed probably that I use will change and I would suggest that you start doing that if you haven't already For elements that you intend to animate you need to decide is this thing primed? If so, I'm going to probably put the will change into my css. If not, I need to do it on demand Probably via javascript, but you want to use it sparingly don't go overboard Transform and opacity are your best friends when it comes to UI elements running Performantly, I hope In the future to be able to say that you can get away with a lot more and actually we are heading to that world with things like GP rasterization CSS containment lots of really good things that might help us limit the work And I mean that we can do more but for today for the cross browser story I would suggest that you stick here If you find yourself in the kind of dynamic end then something like flip where you can remap Expensive properties calculate your transforms at runtime is very useful. Now if all that's news to you And you've never come across like layout recalc styles or anything here are some links inbound phones out Don't know where you can get the slides afterwards as well The other phones went down. Don't care anymore There's the google web fundamentals render performance section complete with udacity course, which will take you through the same kind of content Very useful to get up to speed Secondarily, if you want the source code for those the elements I showed you can get that at the supercharged UI Which take you to the github repo if you want to see me and serma where serma basically spends an hour interrupting me Um, and I try and code. It's like real life Uh, there are bugs as well. It's just it's every time I do one. It's scary, but brilliant Oh, there's a tldw which is like five minutes if you haven't got that amount of time Right. I need to shut up and move on But before I do I just want to say this again We are Hopefully going to be here This is the first time we've been invited to people's home screens That is incredibly exciting, but it's also a huge responsibility We need to act like We deserve to be there and that means taking our user interface work super seriously The web is ready for us to do that. We can do that today with the tech. I've shown that you can I hope that you go and give it a try and with that I'll say thank you very much Now next To tell you how I focused on performance rather than accessibility is I call him bob dodd You can call him doddle max um, the doddinator Sir bubbly of doddly Or you can just call him rob dodson, but don't do that call him bob dodd ladies and gentlemen, bob dodd I think of there's my favorite is doddle max. That sounds like a transformer um See how it's up. I'm doddle max of bob dodd And uh today I want to talk to you about How we can make sure that as we build our progressive web apps that all of our users can access the content in those apps Now paul just showed some really cool examples of how to build amazing components And as he hit on repeatedly in his talk, you know, we know that performance is not just a nice to have performances kind of a crucial aspect of a good user experience We know that users will actually abandon an application if it doesn't have the performance that they expect But it's often the case that when we're designing these components and these applications We're doing so based on our own experience and our own physical abilities So we're designing for the range of users who really see and interact with the world as we do Meaning anyone who falls outside of that range is going to be excluded from our design So these users aren't abandoning our app They're actually prevented from using it in the first place And so as the designers and developers it's important that we not only consider how we interact with the world But we really think about the full range of human abilities And this becomes especially important when we're talking about mobile Because as we use our devices in different contexts and in different environments We may to experience situational or temporary impairment So to give you an example I'm sure many of you have had the experience of trying to use your your phone or some electronic device outdoors when it's really sunny And you need like you can't really read the screens. You're kind of like doing this thing, right? You need some additional contrast on the screen so you can actually read it So if we have a design that also factors in the needs of low vision users folks who also benefit from increased contrast in their reading experience Then what we end up with is just sort of a more robust application It works well for those users. It works well for us as we take our mobile devices out in the sun In other words accessibility just equals good ux I'm getting the crazy slider too. There we go accessibility is just good ux, right? So this is what I want to talk about today How do we make sure that all of our users can access the content in our apps? I'm going to do this by by splitting this talk into three parts So the first part is looking at really the diversity of users that are out there and touching on the accessibility topics that affect them Then I want to look at two big areas that developers often miss which are particularly focused on focus and semantics But I want to start just by understanding who our users are and the kinds of assistive technology that they use Now I'm going to focus on users with permanent disabilities But again, I want to reiterate that issues of accessibility really do affect all of us Ensuring that users with disabilities can access the content in our applications It's just going to make a better experience for everyone But having said that let me get some numbers out there because I think these are pretty fascinating So according to the world health organization about 15 percent of the world's population lives with some form of disability So to put that another way we're talking about around 1 billion people worldwide And we can roughly split these into about four different sort of categories of impairment Those affecting visual senses those affecting motor and dexterity auditory senses and cognitive senses and want to cover each of these individually Starting with visual senses So uh users with visual impairment you can kind of split them into two groups those folks who might be Completely blind and have no vision to those folks who might have limited or low vision So someone who is completely blind might use a screen reader This is talk back on android to interact with their device They may also use a braille reading device to access Their desktop and have it sort of uh translate the content for them in that environment So that's users with no vision users with low vision They may also use a screen reader or No, go back. There we go. They may also Use a screen reader or they may choose to use screen magnification They might use a built-in zoom that's at the browser level or sorry at the operating system level as you're seeing here They might use browser zoom just you know command plus to zoom in the page They may also use something like high contrast mode So here you're seeing that uh the background and the foreground colors have been swapped to increase legibility So that was uh that was vision for for motor impairment These users really span the gamut of folks who maybe would prefer not to use a mouse because they have something like repetitive stress Injury something like carpal tunnel syndrome or maybe even just like a broken arm or sprained wrist Uh all the way to someone who might have uh or who might be physically paralyzed and have a limited range of motion So for these users, they may be using head or eye tracking devices This is an example of a program called dasher which uses a webcam to track the user's head and eyes and help them type They may also be using a keyboard or a switch device as you're seeing here To actually drive their computer. They may also use voice control. So there's a lot of different mechanisms that they can use For auditory impairment These users range from those who are profoundly deaf to someone who is hard of hearing So i'm actually in the heart of hearing camp. I've got about uh 90 hearing loss on my left hand side So for these users you want to make sure that you're not relying solely on sound to convey information in your app So making sure that if you have a video, right, you've got captions that you've got transcripts That you're providing some kind of alternative if sound is part of your interface And finally for cognitive impairment, this is really a broad area that can be difficult to quantify But it spans conditions like 80 hd dyslexia autism just to name a few And while the accommodations for these groups are obviously extremely diverse We definitely find some overlap with things like zooming to make it you know easier to read and and Easier to concentrate on the page. So this is a a chrome extension for someone with dyslexia It applies color gradients to the text to aid in their reading order and help them read in kind of a more linear fashion So broadly speaking these are the four categories that we need to think about when we're working on accessibility in our app Now because accessibility is so broad and the usership is so diverse It can be helpful to have a guide to make sure that we are covering each of these groups And we can find that in the form of the web content accessibility guidelines 2.0 or wakag Wakag is basically a set of best practices which have been put together by accessibility experts to really try and like Like explain what it means for something to be accessible And wakag is extremely comprehensive But it can also be overwhelming. I know some folks look at that and they're like that is not a thing I want to read right now, right? So to help mitigate this the web end group has actually taken wakag and distilled it down to a very easy to follow checklist Which is targeted specifically for web content So if you were watching those videos earlier and you were wondering wow How am I going to possibly cater to all these different users and all these different assistive technologies? I think the short answer is to nail that checklist Okay, figure out what the primary user journeys are in your application If creating a new account is is an extremely important process that you want all users to complete Then take that user journey and for every step along the way Make sure you can check off those relevant checklist items And do this for every phase of your process, right? So get your product manager is bought into it get your designers bought into it and make sure this is you know You're having accessibility audits in your design review get your developers bought into it Get your qa team bought into it and checking these things to ensure that you know the burden does not rely on one person So with these checklists in hand We're actually ready to start exploring some of the fundamentals which will need to actually complete those checklist items and I want to start by looking at focus and really like Like what is Focus like what does it mean for something to be focused in the browser if we really try and get down to first principles So in a nutshell focus determines where keyboard events go in the page To give you an example If I go and I click on this text field that act of clicking on it actually focuses it And from then on as I'm typing on my keyboard all key events are directed to that element Which in this case knows to display The characters as I've typed them Now some users drive their computer Entirely with a keyboard or some other type of discrete input device So for these users focus is absolutely critical because it's their primary means of reaching everything on the page It's also really important for our screen reader users because if we're building something like a Single page web app and we're adding new content to the page right We're fading in a new page or something like that and we need to direct focus to that page So the user knows that it's loaded they know it's available And their screen reader can announce it and we'll talk about that a little bit later on Now a lot of the controls that you're familiar with working with things like button input select All these elements are implicitly focusable What that means is they are naturally inserted into the tab order So user can reach them hitting the tab or shift tab keys on their keyboard And they have built in keyboard behavior support So if you take a select element and you hit the up and down arrow keys, right? You can select something if you hit space or inner it'll select something, right? So they have a lot of goodies built into them already But not all elements are focusable So for instance this this header here this paragraph of text this image of a cat These are not focusable Because there's generally no need to focus something if a user can't interact with it or provide it some sort of input Now if you're worried that someone with a visual impairment might miss Some of this important content don't be that's why we have tools like screen readers It's a screen reader sole job is to read headings and read text and and read the content of an image using alt alt tags So don't make something focusable if the user can't interact with it That might seem like you're helping out, but it's actually detrimental to the user experience And this brings up an extremely interesting and important point Which is that if you build your interactive controls Out of these sort of non focusable elements a div for instance Then your users may not actually be able to interact with it at all So i'll give you an example using Paul's side nav This is actually not paul's exact side nav. I've modified it a little bit But you can see here that i've got my little hamburger menu up there in the top left And obviously i want to tab over and and click that to open my menu And right now my focus is on that little start anchor up there in the header So as i'm tabbing around or hitting shift tab in this case You'll see that my focus never lands on the hamburger menu Because it's a div and a div is not focusable. So if i am a keyboard or switch device user I may potentially never be able to click on that menu ever So how do we fix this? This is obviously a bad user experience Well the straightforward thing to do is instead of using a div We can just use a button element, right? So now when the user goes to tab over to it because button is easily styled We can make it look like a hamburger menu now they're inside of our drawer things are all good A side benefit of using a button element in this case is that the browser actually has built-in Magic that you get for using certain tags like button So a button element if you give it an on click handler and someone lands on it They focus it and they hit inner or spacebar Even though they didn't click with their mouse technically the browser will just say Inner spacebar. Yeah, i'm going to run your on click handler for you If however you have a div and you make it focusable and i'll talk about how to do that later And you have an on click handler on that and someone hits inner or spacebar Nothing happens You actually have to add an additional key down handler And then you have to check which key was clicked inside of the key down handler So there's really no benefit to using these kind of like less or non-semantic elements to do this kind of work In other words don't fight the platform here So the browser has a lot of built-in stuff. It's trying to save you from having to write extra code But i realize, you know, there's not always a native element that has the behavior that you need Or as is often the case there might be a native element, but it might be really hard to style things like You know checkboxes and radio buttons Input file that things impossible um So if you are going to go and build a custom control It's important to remember that you just have to add that keyboard support back in And you can do that using the tabindex attribute So tabindex lets you kind of configure the focus behavior for an element and it can be applied to to pretty much, I guess Many or most html elements A tabindex value of zero Is going to just insert that element into the natural tab order meaning someone can hit the the tab key on the keyboard And they'll easily reach it And also means that we can call its focus method to programmatically focus it So here i've got this very fancy button that i've created right now if i press tab focus is just going to move right past it So i give it tabindex zero now when i press tab focus lands on it and we're all good Tabindex negative one Means that the element will not be in the tab order But this can be really useful If you still need to programmatically focus something using javascript or if you want to like temporarily disable a control So what i've got here is kind of a list control and i might have like a like a hundred items in this list So i wouldn't want all of those to be keyboard focusable because a user's going to hit tab over and over and over and over again To get through them I'd like the entire list to be a single tab stop So user can just like move into it and move out if they need to But when they're inside of it, maybe if they hit the up and down arrow keys or something similar Maybe then i can change which item is currently selected So to do this i'll use a technique called roving tabindex or roving focus And you can see here in my markup my currently selected item has a tabindex of zero And so what i'm going to do is listen for the user hitting the up and down arrow key when they hit down I'll just move the tabindex zero to the next element. I'll call focus on it That directs all of our attention to it But if the user wants to they can still tab out of this control But when they tab back in right the last thing they interacted with is focused for them This is an extremely useful technique if you're building sort of complex controls and and other elements It has obviously great browser support because we have a tabindex for quite a while So definitely commit this one to memory if you're building anything Advanced or super fun like that Now you can also have a tabindex value of greater than zero you can have a tabindex of like five Which just means it's going to jump that element ahead of everything else in the tab order And this is basically considered an anti pattern But i wanted to include it for completeness sake so that you know that it is the thing that you could do The reason why this is an anti pattern is you can end up creating a super confusing tab order if you do this And you're you're mixing matching components, maybe by different authors, and they're using tabindex greater than zero right things could get Wild pretty quickly So in general you want to avoid tabindex greater than zero if you can help it Now i want to revisit the the side nav that paul showed earlier because it presents an interesting couple of use cases for tabindex If we think about a side nav when we open it Right we want the user to be Over there right in the drawer right either clicking a menu item or dismissing it We definitely don't want them Over there behind the overlay Maybe interacting with the page when they shouldn't be But if someone is using a keyboard or a mobile screen reader to open our drawer There's really nothing that automatically moves them into that side nav drawer And i'll show you an example of what i mean by this so This is a mobile safari running voiceover This is hands down the most popular mobile screen reader setup out there about 70 of the people surveyed Who use mobile screen readers use mobile safari and voiceover And you can see this little black rectangle up there on the the reload button So that is where my my screen reader is currently like doing its thing And i want you to watch what happens here So i'm going to start swiping to move the screen reader i'll land on the hamburger menu I'll double tap to select it it looks like i'm inside the hamburger menu But i'm actually or sorry it looks like i'm inside the drawer, but i'm actually still just in the header I'm i was still sitting on the hamburger menu now i'm just moving through the header when i probably shouldn't be I might be interacting with the page when the author isn't expecting it So my user's context hasn't been updated. They're not even sure if the menu is open yet Um and if you have a site that has one of these kinds of menus And you have not done any work to direct the user's focus into the to your drawer This is probably how a blind user or a screen reader user is going to interact with your app So how do we fix this? This is obviously not a good situation to be in Well one approach is to find a suitable heading inside of that drawer I've got this one right here that says menu and that seems like a good one And i'll give it a tab index of negative one So remember when i give something a tab index of negative one, it's not in the tab order The user can't reach it hitting their keyboard, but i can programmatically focus it using javascript So now when the drawer opens, i can call its focus method And now the user is going to be directed inside of here and they can start acting on the drawer very easily So i'll show you an example of that right so same experience We double tap the drawer and we just move right to the menu and the user can keep moving with their screen reader They know exactly where they are and they have that nice sort of continuity to their experience So this is a technique called managing focus and it can be extremely extremely valuable for your user experience It's useful for situations like this. It's useful if you're building a single page web app and you're fading in a new page So super good technique to have in your back pocket Now let me show you another issue that i found specifically relating to tab index and this side nav So this is a more of a kind of a desktop say version of the site And i want you to pay attention to what happens to my keyboard focus as i tab around the screen So i'm going to focus those two things and then it kind of disappears And then it focuses that anchor so so watch that again We're kind of moving around in the header and let me just disappear for a little while And and then we focus that anchor in the page now i'm actually hitting tab the whole time we can't see our focus ring anymore And what's happening is because we have that drawer off screen and because inside of that drawer we have anchors and things like that Focus is just moving off screen. It seems like it disappeared, but it's actually just you know over there somewhere Where the user can't see it now? We probably don't want someone to be able to Interact with off-screen content, especially for kind of trying to hide it on purpose again This would cause sort of an error state in our application possibly and it can be very confusing for the user So how do we fix this by the way? I see this all the time you should go to some big websites and start tabbing around This will totally happen to you Okay, so how do we fix this because it's a it's a super weird situation to be in Well the first idea is like well the thing's off-screen, right? So let's uh, let's set it to visibility hidden. You know it's off-screen that makes sense. It is hidden in a way And this would totally work But if you recall in paul's talk he talked about primed elements and he talked about flip and he talked about this idea of Having your elements already kind of like in the DOM already like ready to go And if we set them to visibility hidden then we're going to destroy the compositor layer, right? We're going to have to do all that work all over again every time the user presses a button So that seems like maybe that's not the best solution And to me this is really frustrating because I feel like developers and users should not have to choose between 60 frames per second animations And good accessibility So I tried to come up with two solutions to this problem The first is to Ignore paul and say I win and I get what I want and set it to visibility hidden anyway um And the reason why this is potentially workable is because as paul mentioned in his talk You do have about 100 milliseconds from the time a user clicks on something Until the time, you know, you need to start animating So if our drawer is simple enough Then maybe we could get away with actually setting it to visibility hidden and recreating that layer So the way we do this is we listen for the transition end event for when that drawer is off-screen Right, I check to see. Hey, does it have the side nav visible class? Which was you know, how I know that it was either on-screen or off-screen If it doesn't I'm just going to set it to visibility hidden and do you sort of like vice versa for when we animated on-screen So what does this look like in the timeline? Here's paul's original version And the the time that I am interested in is this little block right here So that's the time the the yellow bit there is the click the the end of that blue Rectangle is sort of when we ship the next frame. So right now it's about eight milliseconds in paul's current version Well within that hundred milliseconds range, right? And if you look down here Uh, you can see the amount of painting that we're doing So I've got these two little chunks of painting that are happening because this thing's already in the Done, we don't have to paint it much So here's the version where I set visibility to hidden and you can see that there's Definitely more paint work going on But if we look at our our time range here, it's about 10.4 milliseconds So we added a little bit of time but but not too much and a lot of that time was actually idle time So in terms of uh, you know, how this frame stacks up with with paul's version They're they're pretty similar And again, it's because we can get away with this because the drawer is super simple Right, it's a very simple element if you had a bunch of images and much icons inside of there And that paint may be more expensive. So this leads me to option two which I am calling the detabinator Unfortunately, there's really no easy way to remove all focusable children of an element from the tab order You have to go to every single child and set it to tab index negative one You can't just set it at the parent and have it cascade down, which is a bummer So that is basically what this library does for me I created detabinator And I give it the side nav element and when I set it to inert I set all the children to tab index negative one. I set it to inert false I restore all of their tab indexes the way that I do this is really gross, but I wanted to show it um So I have this query selector all right and I have this Lovely query selector string inside of there to select everything that could possibly be focusable inside of an element And this is you know, this is not entirely bulletproof There's weird quirks here if you have like links inside of svgs or stuff like that Like it may not be bulletproof. It may not be perfect, but it does probably for for general use cases do the right thing Then for each of those children I'm going to loop through them if they already have an explicit tab index I'm going to save that remember when we set that menu to tab index negative one because we wanted to manage focus So i'm going to hold on to that so I don't lose that information And then i'll set everything to tab index negative one regardless And when we're going to open the drawer, I just restore all those values Okay, so here's the detabinator version in the timeline You can see Our our little block of time right here is back to about eight milliseconds 8.4 milliseconds So we're pretty similar to where we were with paul's original version And if we look at our paint time we're back down to sort of like two little blocks of painting So hopefully we're in sort of the same ballpark now again these there's there's sort of trade-offs to each of these right the visibility One you have to do a little bit more more work there in terms of painting with detabinator You would also have to add things like are you hidden to prevent a screen reader from going in there So there's additional work that would be required in that case But again, what I'd say is you know, maybe if you if you're if you're running into this problem Try one solution or the other measure it see which one works better for you and which one your team prefers Okay, we talked a lot about focus. I'm going to switch gears now and talk about semantics So this is the other half of of ensuring we have a good user experience Uh semantics is really crucial for making sure that our screen reader users can understand the content of our page And the first question that comes to mind when I think about semantics is like Well, what does good semantics mean like again? Let's get to first principles What the heck does it mean if something is semantically like rich or right or whatever, right? And how does it actually benefit someone and answer this question it helps to think about this idea of affordances So an affordance offers or affords a person an opportunity to perform an action And a teapot is a really great example So a teapot just based on its physical design has affordances it has a handle And because i've seen other things in the world that have handles I know that I can walk up to a teapot and pick it up by that handle and interact with it No one has to explain to me how a teapot works Now when it comes to graphical user interfaces Affordances still represent the actions that we take But now they're kind of more metaphorical. So a button is a good example, right? Someone can't like go You know touch the screen and feel the button So we try to make it look like a three-dimensional button that you might actually interact with in the real world But the obvious problem with this is that if someone can't see the screen then they're going to miss out on those visual affordances So we need to make sure that the information in our application is expressed in a way Which is flexible enough to be accessed programmatically by assistive technology Which can then create an alternative interface for those users So i'll give you an example of what i mean by that here. I've got some semantically rich markup So i'm using a select element to create a list And this is going to generate a visual ui Right But because i've used good semantic elements, it's also going to produce this alternative ui It's going to produce a spoken ui for a screen reader user Now roughly speaking for for just about any element you can expect some subset of the following semantic information to be expressed for it The element will probably have a roll So the select element in this case its roll is pop-up button It will have a name and i don't mean like a name like the html name attribute But you can think of the name kind of like it's label Or the sort of the computed text value of that thing The element may also have a state it's optional some elements have states some don't And it may also have a value again. That's optional, but in this case we have a value of no preference here So what's happening is when we write html the browser does two things It generates a graphical user interface And it generates a separate accessibility tree, which is just a collection of all that semantic information that that I was just going through This tree then gets handed to assistive technology like a screen reader And then that produces a spoken ui for our user So this is actually why semantics really matter even though even though nav and div Look the same, right? Because they don't look like anything they just look like a container semantically it produces something very different in the accessibility tree So as I mentioned, uh Just like with focus native elements many of them have implicit semantics So for example a voiceover on mac when I focus an input element with type equals password It's going to announce secure edit text to the user And just like we saw with focus when we try to bolt functionality Onto non-semantic elements like a div and we end up missing up on all missing out on all these goodies that the browser is trying to give us for free So here's another div button another very fancy button and it's it's got tab index zero So it's focusable for sure But when a user lands on it with a screen reader the screen reader will say group Because it did it's just a grouping thing. It's a container, right? But that definitely does not say to me that I should click on it So again, don't fight the platform here whenever possible use native elements because you're going to get good rich semantics for free And just as an aside Like I hope at this point no one is considering writing a div button ever again if anyone leaves here and writes a div button I have failed all of you But there are times when you're going to need to build something that just like doesn't have a native element equivalent You know or you need to just kind of go off-road and do your own thing and in those situations You can use the web accessibility initiatives accessible rich internet application spec or aria so Aria allows you to specify attributes on an element and then basically modify that element semantics You can think of it like doing surgery on the accessibility tree However semantics is the only thing that aria changes aria does not change behavior So I used to think if I put like a roll equals button on something that it magically like became Focussable and worked awesome with a keyboard It's not the case all it does is change the semantics that get expressed to assistive technology So let me give you an example of using aria in practice. So here i'm going to build a custom control i'm going to build a checkbox a custom element checkbox and In this box down here on the bottom right i'll show the output from my screen reader Just the the textual output right and the first question when I look at those checkboxes. Hmm. Okay. I'm building a checkbox I want it to be accessible. What do I need to add to this? What sort of aria do I need to add? Now there's two approaches here the first you go look at the aria spec which comes with this very helpful diagram Or You could go check out this document called the aria authoring practices guide and this document is a bit of a hidden gem It is pretty freaking cool. So over on the left hand side there. You see all the ui patterns that you could probably imagine There's a ton of them in this document right grid dialogue tree like whatever you're trying to build Checkbox for instance is included in there So you click on the ui pattern and i'll take you to a little section And it's just going to walk you through all of the support that you need to add to that element In particular, there's a whole section down here dedicated to the aria that I need to add to a custom checkbox So it says it needs to have a role of checkbox It needs to have an accessible label which we'll talk about it needs to have a state of aria checked if either true or false Okay, cool. So let's add this to our our checkbox I'm going to give it a role of checkbox And you can see now my screen reader is announcing unchecked checkbox nice Now in the world of aria role is the absolute most important Attribute everything falls out of the role. Okay. There's a lot of aria attributes Which don't even work if they are not paired with the proper role So and you can also see that now my state is just defaulting to unchecked because the role right So it's it's like trying to start doing stuff for me. It's like coming alive, which is cool But you see that my checkbox actually is checked. So I need to change that state So I can add aria checked and get set it to true And aria is sort of unique in that you always need to pass it like a literal string value of true or false Most html attributes do not work this way, but this is the case with aria. It's kind of a weird quirk Now the design pattern doc also mentioned I need labels for this thing and there are a couple options for how I can label an element The first is aria label, which is really just a label that you can apply directly to an element A good use case for using aria label is something like a hamburger button where I probably wouldn't have any other text on screen to explain this thing But I need to explain it for assistive technology So what I can do is take that button and add an aria label of main menu and now it'll announce main menu button Nice, okay, that's good That's one option. The other option is aria labeled by so aria labeled by lets you specify another element to act as your label It's sort of similar to using the label element like you might do with a native input But that that element really only supports a few kinds of children whereas aria labeled by can be applied to just about anybody And the cool thing about aria labeled by is that it can be composed So I can take other elements and combine them together for a bigger label in this case I got this button that says shop now and if you look at our text up there the screen reader is just going to announce shop now button I don't know what i'm shopping now for I'd like to combine it with that header So using aria labeled by I can take both the header And the id of the button itself and compose them together to create the label men's outerwear shop now button Nice, so this is what I want to do in my checkbox. So I have this little span here I'll give it an id Drop it into my labeled by and now the stream reader is going to announce that I have sign up Checked checkbox. There we go. Nice Now if you are building controls and you want to verify your work is correct I highly recommend you check out the accessibility dev tools extension created by my teammate alice box hall This thing is awesome It lets you inspect your elements accessibility properties the same way that you inspect css and other things like that So here's our sign up button And I open it up go to my elements panel find this element And then I can go check out its accessibility properties and see now its role and its its values and its name and all these other cool things So I don't have to go around with the screen reader and manually test every single element So this is super handy to have you can find it at bit.ly Slash a11 y dash dev tools Another cool example in the progressive web app spaces this app created by the polymer team called shop I really love this app because I think it shows off that you can build these bleeding edge beautiful experiences using web components using All the service or sorry all the progressive web app tech that we're talking about but still have a be really accessible too So you can see the text down here. This is the output from my screen reader and as i'm navigating around It's giving me lots of really useful Actionable feedback right it's telling me the the proper thing that i'm interacting with So Definitely go check out shop you can find this at a github.com slash polymer shop If you find any accessibility issues, please file them. We want this to be like a like a show piece of web components and a good accessibility All right, we covered a lot. Let's wrap it up really quick Three big things that I want you to take away When you're planning your applications make sure that you're really nailing that webbing checklist familiarize yourself with a tag And ensure that you know you you can go through those user journeys and for every major primary use case You can check off the relevant checklist items If you're building controls you want to ensure that they have good keyboard support and that everything is Focusable use native elements whenever you can because it's just going to save you a bunch of work If you need to create your own elements to use something like tabindex to make sure that the user can interact with them Also make sure that you're offering the right affordances in your app So again use native elements because they have rich semantics for free But if you need to go off-road can use something like aria and that aria design pattern stocks Seriously, that thing's a lifesaver. So definitely check it out Now if you're interested in learning more about accessibility Myself and alice box hall we have put together this entire udacity course. It's launching today I think actually so if y'all go sign up you'll be some of the first people So it's bit.ly slash web a11y. This is a multi-week course. It goes super in depth on all of these topics So definitely please go check this out Finally the main takeaway that I'd like for you all to leave here with is this idea that accessibility is just fundamentally good ux Ensuring as many users as possible can access our content Should be our primary goal at all times Cool, uh, so that's it for me Thank you so much coming up next to talk all about progressively enhanced markup Please give it up for my friend Eric Weidelman Do we have the slides? There they are Thanks for sticking around everybody We're going to talk about how to use web components to build web progressive web applications And the notion of progressively enhancing your markup using custom elements So this is me. It's at ebidle on twitter and github. I got crazy sometimes I'm a digital jedi google which basically just means i'm a web developer that helps other web developers outside of google build Really awesome web apps And I built a number of web apps At my time at google so we've worked on things like developer sites for html5 rocks We built developers chrome.com Polymers website chrome status.com Santa trackers on a developer site obviously, but it's kind of a fun project that we work on on developer relations So you can track santa around the globe see where you deliver this presence We built the codelab site that you see here today at the show In polymer, and we've also worked on the google i o progressive web app the last couple of years Speaking the last couple years. I've gotten really excited about web components All these emerging standards several new apis that allow us web developers to build applications code reuse Ability these are really good things for the web And it's important to know it's a set of emerging standards. So it's not just one api It's it's a few and you can use them each individually. That's totally cool But together it becomes a web component and it becomes very powerful So they allow us to extend and create new html elements. That's the core. That's the principle here And over the last four or five years since the standards kind of first started to evolve We've grown the community quite a bit. So there's web components.org which you can check out It's got articles. It's got people there contributing That's also where the poly fills are hosted if you want to actually write an app in production You can do that using the poly fills so check that out. It's a great resource But browser support's actually been been lacking So i think chrome 36 was the first browser to land all of the web component apis So you can create a component without the use of a library. That's really awesome But browser support's been lacking And so if you take away nothing today from this presentation take away this slide Basically, what's happened is that chrome implemented the apis very early on so shadow dom, custom elements, template and html imports This is what the api calls looked like. These are called now the v0 apis What's happened is that the browsers recently got together and said hey We want to you know tweak a little things here and there about each of these specs And they decided and came to consensus and what's going to happen now is there's a new version of shadow dom and custom elements We call these the v1 apis So if you've learned about web components in the past all the concepts still apply same stuff still applies It's basically just syntax and name changes In this presentation, i'm not going to talk about template which is actually supported in all the modern browsers now Which is great. You can use that without a polyfill and i'm not going to talk about html imports I'm just going to focus on the two that have have changed And the implementation in the browser is is well underway So chrome has started in on custom elements and shadow dom you can play with these today in canary with a flag Over at firefox wilson page who's an advocate there tweeted this recently So they're actually started in on shadow dom v1 custom elements has an open bug. They haven't started that yet Safari last week in fact at w w dc and now it's safari 10 will ship with shadow dom So that's two browsers this year alone will have shadow dom and they've also started in on the new custom elements api We thought that might land in safari 10, but they just didn't get in on time And over at microsoft edge is is playing a crazy catch up implementing all these things service worker push notifications You see shadow dom and custom elements and web payments on there. So very exciting times for web developers The stuff is coming in hot love it Browser support really matters turns out native support really matters We don't want to use polyfills for the rest of our lives, right? We don't want to drop in a lot a needless library that we don't have to and the Notion that polyfills goes away over time is the promise of a polyfill The other reason browser support really matters to me is because if you look today at all these libraries and frameworks They all produce and allow developers to create components But there's sort of no standard way to build the component Some use a lot of javascript. Some use more html and javascript. Some just use a massive amount of html So the goal of creating a tab strip is the same right? You want to create a reusable tab strip But the way you get there is very different across the board And so that's what web components is here for it's here to have a standard way to create reusable components So a web component tab strip would look something like this. It would be declarative. It would be my dash tabs We'll just call it that it's got a selected attribute that you can use to select the tab that's Should be selected and it's got div for its content. It's got html attributes. It's very readable and very clear what's going on here The other thing that people often forget about is the fact that it's just DOM and html that we're creating means we're integrated with the browser We're integrated into the platform So rob mentioned all these great accessibility features that the browser and the html elements already give you We're integrated with that we can take advantage of what's already there and don't have to reinvent the wheel ourselves And we're also integrated with every web developer's best friend, which is the dev tools And i'll show an example of this this is polymers old site and i'll just fire up the dev tools and show you what happens and how you can Kind of debug a web component. So this is a tab selecting tab strip that we have for our code that you can kind of poke around See the code and then you see the live output on the right there So i'm just going to open the dev tools open the inspector and immediately it's just DOM and html So i can just poke around with the inspector see what's going on see how this custom element is built You see that there's a shadow down attached to some of these elements I can open up the console and i can start tweaking properties DOM properties of this element So i can change its selected property and you can see a live update in the DOM Since we're integrated with the platform in all white ways we can actually change css right and affect how this component looks Just by changing the color of the text of one of its panels I can discover it's got a panel's property and it's got an api it's got methods So things like updated panels we can call that and it does something who knows what it does But we're discovering that in the dev tools and it's got a bottom property This one happens to actually change the way this thing renders And by changing that you can see the live DOM update So this is really cool and the fact that we're integrated with the tools and the platform means we can build apps even better So for the rest of the presentation i'm going to show a lot of code Web components is one of those things where it's a developer feature. It's for us It's not a fancy feature like web rtc or web gl So it's not sexy. It's actually for ergonomics. It's for you guys to produce a reusable code So let's dive in let's talk about custom elements custom elements is sort of the foundational piece of web components and allows you to create new html and tell the browser about that html So let's build a button. There's no better way to to actually learn this stuff than actually build something So we'll start simple we'll build a very simple component a button component Now if you probably know right html already has a button But a lot of people stopped using button over the years. It doesn't look that great You know it renders differently in different browsers But it's got a lot of great built-in features if you think about it right rob talked about focus ability and keyboard behavior It's got that built in when you tab into the x into this thing It actually highlights itself and it has this effect this gradient that applies It's got special properties to treat it like a button It's got a disabled attribute that you can apply that actually affects the rendering of this element And if you put this in a different context if you put a button inside of a form It actually does something different right it submits the form and participates in the form submission So this is magical and kind of cool. We get all this stuff for free just by declaring this on the page But of course we want to create a leave and better button We'll call it a fancy button that's got a nice little ripple animation when the user clicks on it It's got a box shadow if you apply this raised attribute And we can make this thing behave exactly like button So i'm going to do what rob told you not to do which is create a div button Don't do this. This is just building up the example But this is the way you might start off with this right and you could start out by using button and then remove the The default styles the browser applies, but we're just going to have a blank slate here Create a div give it a class better button and essentially that class is just going to style this thing to look like a button So it's got a box shadow. It's got some border radius It handles disabled state if you have this disabled class on it So we're just making a thing that looks like a button But of course if you want this thing to quack like a button you have to do some things So we'll add a tab index zero and a roll equals button We'll actually tell the screen reader that this thing is going to be a button and will allow users to keyboard into our button And maybe right we want to have this ripple effect. That's that's the extra functionality We're adding to the button So we'll rip the element out of the DOM and attach an event listener for that And if the button isn't disabled we'll allow people to click on it and we'll draw the ripple animation So very simple not much going on here But this has a couple problems the first is that users have to know how to style this thing themselves They have to kind of know all that magic that we gave them put that on their page And the second is that we have to add a click handler for all instances of the button that are used on the page It's not very reusable. I can't really reuse this thing Users have to add their own tab index equals zero and roll equals button It's not very componenty So of course we can do better and the answer is to use a custom element for this we can create something that's reusable So the first thing i've done here is just replace div with the name better dash button I'm creating a custom element and custom elements have to have a dash in their name That's just part of the specification. We are calling our button a better button And instead of css classes to style this thing. I'm just going to use html attributes It's a little cleaner to read and it's going to map really well to the javascript properties We're going to define on this button In my css all i've done is just replace classes with that new tag name nothing's changed about the appearance of this thing Of course, we can do even better. We can progressively enhance this markup from its Self right now to something better. We can give it an api and use javascript to do that And so the way you create a custom element is just define an esx class We'll call it better button and it's going to extend the browser's native html element So it's going to gain all of the dom api And since we're creating a button maybe you want to have a disabled property just like the normal html button has So we can do that in esx just to define a getter and a setter for disabled And in this case what i'm doing here is i'm keeping the attribute in sync with the javascript property So if somebody changes the javascript property in javascript We're going to actually reflect that value back out into html and set the attribute on the html tag in the live dom And other properties on the web today do this too the hidden property The id property if you set them in javascript, they'll actually update the markup as well So we can do that in custom elements Something else you can do is go the other way So if somebody tweaks an attribute you want to get a notification about that you want to react to that And so for that there's two special things you can do in element code The first is to define and observe attributes array This is sort of a whitelist to say any attributes in this array. I want to get a call back for And so what the browser is going to do if it observes a change to one of these attributes is call your attached Attribute change callback. It's going to be provided the name the old value and the new value that the attribute is changed to And here what i've done is basically just look at the disabled property when that happens and set a tab index In an aria disabled attribute accordingly. So we're kind of mimicking a button the button again by adding this functionality ourselves Something else you can do is run code every time an instance or your element is degraded and declared on the page So to do that we'll just define a constructor And the first thing you need to do in element constructor is call super. That's just part of the spec It needs to set up the prototype correctly And then from there you can put in whatever you want. So in our case, we're going to define a key down listener We want to actually have when people press enter on our button to react to that and that's what this code does And then we'll add that click listener that actually adds the ripple animation So if the button's not disabled we'll allow people to click it and draw the ripple at the user's click location We can also react to when our element is added to the DOM or removed from the DOM And so for that we can use the connected callback This is a great time to do any setup work in our case We're adding the role for screen readers and we're adding tab index zero at that time And disconnected while we're not using it in this component is actually very valuable for things like cleanup So if you add a bunch of event listeners in your component or do other kinds of setup you can remove it at this time The browser will call that method If you're curious on how draw ripple is implemented. It's pretty simple This is the way I've chosen to implement it just a div with a ripple class that styles this thing to look like A ripple effect. So it's a div with a border radius that kind of just grows and fades out Pro tip. I'm using css containment here. We're creating a reusable component that's self-contained Mine as well tell the browser to optimize this forest so it doesn't do it knows to scope layout and paint That's awesome. We can just basically drop that in in our web components And the other thing I want to point out about this code is i'm doing i'm basically creating a declarative style api And providing a little bit of functionality and flexibility for this component So if some user that uses better dash button Styles the color the font text with red We're basically styling that the same as the background ripple is going to be styled the same as the font color So this is kind of cool. You can do these things in your components and document how this stuff works for users Now we've got a component. We've defined its es6 class The last thing we need to do is actually tell the browser about this new element And so the way you do that is to use the custom elements interface and call the define method You pass it the tag that you want to create and the class definition that you just created And then from there the users can use this element as if it was a div or a span or any normal html element They can declare it on their page. They can use the new operator in javascript with the element constructor Or they can call document create element the same tricks apply that always apply to the web So that's a lot of stuff, right? If you think about it, there's a lot of css involved to make it look like a button We have a class that mimics all the behavior of button And the last thing we do is have the registration. We actually tell the browser about our new element We can do better we can progressively enhance what's already available in the web platform So again, we have a button already in html. Why are we reinventing the wheel? Why are we mimicking everything it does for us? Why don't we just progressively enhance the button element? Well, sure enough, we can do that custom elements allows you to extend html that's already existing in the web So instead of extending the html element, we're going to extend the html button element We're going to extend the specialized version of that element And then what happens is this is our entire class definition So all that work we had to do before with tab indexing and key down listeners All of that stuff goes away because we get the DOM properties and methods that button has for us just for free And then we add the extra functionality in this case. It's that ripple animation with the click handler So this is really convenient. This is called a customized built-in element And the way someone declares this on their page is a bit different So instead of using better dash button, they're going to actually declare a button and it's going to be an is better button So this button is a better button. That's how that reads So we've done a lot, right? We've made a custom element. It's reusable. It's a fancy button little little sexier than the normal html button But it's got all the benefits that the original one had in it I want to take it a little bit aside and talk about this call here The notion that you you call custom elements dot define with the tag name and you kind of upgrade the element What's happening is what is called an element upgrade. This is part of the custom element spec You kind of endow your markup with an api by defining some javascript that gives it its api And its methods and properties. So you take an html element and you make it something better So the notion here is that custom elements are really just progressively enhanced markup You're taking something that doesn't have any functionality and you're progressively enhancing it to have functionality We've taken advantage of this notion of element upgrades on the developer's code lab site We built it in polymer And if you dissect this thing you can actually see where the components live on the page So our search bar is a component Our sorting and filtering widgets are components And also this main section in the center is a card sorting element that knows how to rearrange its children based on the user's sort and filtering So that's how this thing is kind of structured. I want to show what happens when we load this page I'm going to slow it down to a 3g connection so you can really see the effect So we'll navigate to the page and instantaneously it paints the browser turns out is really good at just painting pixels html css very small payload And then eventually what happens is the components fade in we'll see that one more time because it was kind of fast So first paint is really fast and then as the components upgrade and get their super charged api they fade in asynchronously So turns out this is really fast. I clocked this at about 2.2 seconds for a first paint on a nexus 5 3g connection And of course this would get even faster with a service worker if we had caching and the user came back to the site So the way you do this is to use another feature of custom elements. It's the css colon define So you can basically pre-style elements before they're ready before they get their javascript api and you call custom elements dot define So in our case, I'm styling that paper tabs that selecting widget Basically giving it a little layout giving an initial height to kind of replicate the styles that paper tabs defines in it And I'm also just hiding it right on page load. It's just hidden and then when the browser removes this defined pseudo class Our element will transition in So the effect is that these things kind of just take up placeholders and you see them just fade in when they're they're ready The rest of the page is very simple just a little bit of markup at the top to describe the website We have that sorting and filtering section. That's got some custom elements in it the paper tabs element And the main bulk of that that intersection is this card sorting element. It's just a custom element It's on the page ready to go everything server side rendered So all these links just show up on page load and they're styled to look like a codelab card So this is great. This paints really fast the contents there available users They can start reading it right away and then eventually at some point in the future We actually register these elements in the browser And at that point that's when the card sorting element gets its api gets its filtering api and its sorting api That's not critical on page load. So it's a great great story for progressive enhancement So let's think about what we've done so far in a very short period of time. We've created a reusable component It's got custom elements api. It's got reusable styles If you drill down into the dev tools, you can actually see a problem though One of the implementation details is kind of leaking right that's this ripple div that we're creating dynamically is kind of mucking with the user's dom It's taking up space Implementation detail. They really shouldn't see that We can fix that The answer here is to use another part of the web components, which is shadow dom So if you think about today's elements, there's the select element Right and you drop a couple a couple of option tags in it give one of them the selected attribute And somehow the browser magically knows to render this thing as a drop-down widget and select the correct element That's kind of cool If you add the multiple attribute to this html element, it completely changes the way it looks So instead of a drop-down you get this multi select widget Pretty magical The video element a couple a couple of attributes on the single tag You get an auto playing video with uh, you know video controls for free. Where did these use ui controls come from? An input type equals date or any of the various specialized versions of input are pretty cool Instead of a text box right text input you get a ui that allows you to select a date So this my friends is shadow dom shadow dom allows us to do the same thing the web The native browser vendors have been using for a long time They use shadow dom to create these widgets and hide away markup and css We can do that inside of our component as well So in order to use shadow dom inside of a custom element, it's just one or two lines So inside of the element constructor we can call this dot attach shadow That's going to create a document fragment a shadow root That's going to kind of attach itself to our element and we can fill that document fragment with anything we want any markup you want In our case we're bringing in those styles from the page so users don't have to define them themselves This is great because styles inside of shadow dom are scoped to your element So that means styles and selectors aren't going to bleed out into the page and page styles aren't going to bleed into your component So that's why you see i've replaced some of the the selectors here. I've changed better dash button to use colon host That's the way you style the element itself inside of shadow dom And my selector for the ripple div has gotten simpler. We're just using dot ripple now And that's because again these styles are scoped. We can use common ids again We can use common class names again They're not going to collide with the main page because we're inside of shadow dom which has this scoping for us And the last thing you see is i've moved in this ripple div It's become part of kind of the implementation detail of my component Users are not going to see this inside of their dom So let's take a look at this when you do this when you call this attach shadow root What happens is that you get a shadow root attached to your better button. That's great We have shadow dom in the works and you can see that we have the styles You know scope to this element. You can see the actual style information This thing looks like the button, but it's actually lost something. It's lost that fancy button text that we have And that users have declared And so the reason for this is that shadow dom is kind of like a party you have to invite things into it You have to invite things in the outside world to render inside of your shadow dom For this you use composition with the slot element slots another element That's part of shadow dom that you can use for bringing those things into your shadow dom So let's say I have a shadow dom that looks like this. I have style information and a slot element What's going to happen here is that when someone declares a better button on their page Fancy button text is going to get projected into this slot It's going to render at that location inside of my shadow dom and the effect is that you get the text back That's exactly what we want You can also have default content So if someone doesn't provide the text themselves when they use our component you can render just a button as the default text And you can have an entire dom tree in here if you wish doesn't have to just be text And there's also a more advanced form. It's called name slots So we can have as many slots in your component in your shadow dom as you want In this case, we're defining a slot with the name equals icon and a default slot that doesn't have a name When someone uses our button like this, maybe they want to have a little gear icon next to some text What's going to happen is that the name slot is going to get projected into that location It's going to render in that slot and the settings text is going to render in the other slot because it's not using a name The effect is exactly what you expect, which is that gear icon and a settings text So I think of composition. I think of a slot element as kind of a declarative api for your element It's a way to really provide a level of Functionality and customization and this is exactly what the select element and those other native elements are doing allowing for You to configure their ui based on attributes But let's say somebody wanted to use our button like this They want a ginormous pink button with a lot of padding and a different ripple color Well, since we brought the styles into our component, how do you actually allow for this type of customization? The answer here is to use another new web platform feature, which is css custom properties essentially css variables So what we can do inside of our shadow dom css is basically have placeholders for users to fill if they want if they So choose Support for this is really good right now actually everyone, but edge has this available as a native feature So when someone uses your custom element, they define some css for better button They can fill in the values if they so choose so they'll define in this case They're defining the button padding and they're defining the size of that ripple animation We're going to create and so in this case we'll use those values But if they didn't provide them again, we'll just use our defaults that we set up ourselves So css custom properties is a great way to have like placeholders and allow people to customize your component and the styling of your internal elements in your component So that was fast. Let's recap what we did in a very short period of time in less than 30 minutes. We created a reusable button It's progressively enhanced from the native html button Which means we have all the benefits that the browser in that element already gives us It's got keyboard behavior all the stuff that rob talked about baked in It's self contained using dom and css scoping of shadow dom It has an imperative api a javascript api. Thanks to custom elements It's got a declarative api. Thanks to composition and the slot element and shadow dom And it's also configurable so we can have people can use it in different ways with html and they can also configure the css That's pretty cool So this is why i'm so excited about web components because it allows for this flexibility allows for the good reuse on the web again And this is just a button you can imagine building an entire app out of components If you don't want to get started So if you do want to get started Go back You can actually check out and try to use web components yourselves So polymer has put together a really awesome set of reusable and very useful components for different types of things And there's also custom elements.io that has a list of web components. You can check out So with that that's all the time i have Again, this is me on twitter if you want to hit me up with questions I think now we're going to transition to a break. We're going to take 20 minutes because those guys went over Um, but I really do appreciate you guys sticking around. Thanks for your time. Go componentize the web So welcome to totally doing tips. This is an episode on dev tools We're going to talk about our newer progressive web app tooling Yeah, so the reason we have to do this is we record an entire video episode And then everything changed it's Tuesday. So dev tools has changed Right. So the resources panel has now been replaced by the shiny new application panel So i'm currently on a progressive web app. This is smaller pictures and some of the newer stuff that we We let you preview include like your web app manifest Yeah, so basically web app manifest is kind of if you've ever built web apps, so you've had to do icons for Different devices and browsers and you had to put in lots of link tags Manifest is jason file where you can put all of that stuff in one separate resource And the browser will only go and grab it when it needs it Yep So we summarize everything from like your name your short name through the different theme colors and background colors that you're using We show you your orientation chosen in your manifest file and then just like preview all the different icon sizes You might have set up so i've got like all of them because i'm crazy You are crazy. I'm crazy. It also lets you emulate as a home screen if you click on this little link here That's just like the experience where it'll show you okay. Well, what do you want to name this thing? So the reason this is important is because whenever you click on add to home screen What it will do is it will go through all of the criteria that chrome looks for To basically decide whether it's going to show the user the banner or not So it'll be things like does the web app have a service worker? Does it have a short name? Does it have theme color? And if any of those criteria aren't met it will print out an error to the console just saying Yep, you need to have this and because it's not there. I can't do at home screen Cool. So the next thing we're going to take a look at is the service worker panel So debugging service worker has been like historically really really painful Um, and I think dev tools has nicely evolved over time to make that experience a little bit sweeter Yeah, this is definitely like the best version of it It's it's just really hard when you're starting out to understand what is going on when you're doing this stuff for the first time Um, but I think there's definitely like the nicest version so far Yeah, so we're going to quickly walk through all the options here So the first one is an offline checkbox and basically if we go and we refresh you'll see that the app is working offline This just emulates offline in the same way that the network throttling drop down will let you do noise Fairly useful when you're testing offline support with service worker The next option is update on reload which forces your service worker script to update on refresh So the reason this is a super handy is Before this existed what you'd have to do is you'd make an edit to your service worker You'd save it you'd go back into your browser you'd refresh And once you've refreshed the page it will still be using the old service worker because your new service worker Will be grabbed by the browser it will go through an install step And the new service worker can't take over the page until the old one's gone So when you check update on reload what it's doing is it will unregister the old service worker register the new one And once the new one's ready to go it will refresh the page so that the page is using the new service worker So it's one checkbox. So there's kind of a lot of stuff going on behind the scenes and it's super useful Next up we've got bypass from network which will bypass your service worker script and load resources from the network The reason this is handy is when you're not working on a service worker and you're working on other files You don't want anything to be pulled from the cache. You just want to be using the files that you've just changed Then we've got show all and show all will basically show you every single service worker that's registered Um, because we've got like an increasing number of sites and apps using this you might find this a little bit noisy I just say you're very unlikely to ever want this until something like foreign service workers come in but Yeah, we're just we're just letting you know that it exists Today unless they change it tomorrow, but it's it's here today at least What else does this let you do? Okay, so you can update your service worker. Um, there's a push Option as well. What does that do? Let's let's head over to your demo. I'm going to guess it's going to do something with push messages You're so bright path you Right, so this is a push demo matt wrote a while back We're going to go and we're going to enable push notifications and your demo worked this time. Yes Right, so what we're going to do is if we click, um push it's going to emulate a push event You'll see that we get a push notification This is kind of interesting because this is the first time I've actually Seen or like tested this myself in canary and they basically added a new feature where it's it's populating a little bit of data in there Um, which is kind of super interesting slightly weird with the fact that you can't determine what the data is But it's awesome that it's there because it does mean that if you wanted to check What data would look like when it comes in your service worker? I mean it's now something's there. It's awesome Sweet. Um, what happens if we click send a push via xhr? Does anything happen? It should do it should do Did I actually oh, I didn't there we go I don't know you did a gcm just took a while to kick in okay, so there because there's no data It's just like a super generic. Hey, thanks for sending this message. It's sweet uh, you can also go and click on the uh Little name. Oh, you've got a minified service worker. Yeah, man. What what do you do? Okay, let's let's go to someone who hasn't done that and if we click on source you can go and you can check out The uh source to your service. He just doesn't care about users data So the reason this is actually super cool Is the fact that you can now add breakpoints to your service worker like you would any normal javascript files So when that Code gets executed in the service worker It will actually stop the service worker from running and you can start debugging stuff like you normally would with dev tools Which is noise sweet you can also um, so you can see that we've got like these activity indicators for the status So green means that something is active and it's running Um, you can stop your service workers. We can go and do that. They'll say activate and stopped You can focus your clients. So we're currently focused You can also hit details and it'll show you in line any of the exceptions or error messages you've been getting So the one thing that used to exist here that's been removed is you should be able to have like an inspect Button that you would click and it would open up an entirely different dev tools just for service worker I still kind of like having the two dev tools one for the page one for service worker But I think the dev tools team are trying to Get everyone to work just out of the one dev tools and change different contexts So in this case all the service worker logs would show up in the one console and you select different Um frames within that so it's kind of interesting. This is the only thing that i'm Anxious about I guess But this is quite a nice way of at least servicing just the errors because I'm add I'm just going to click clear and now all of our problems have gone If only life was that simple only life was that simple Clear storage is basically the best thing ever If you're developing any non-trivial progressive web app and you know, you're trying to support offline with service workers You're maybe using um, you know storage mechanism like index db or local storage or session storage You've probably run into the situation where you know You need to manually go in and clear all of your different storage mechanisms out And then head to different panels to unregister service workers and it's just it's this whole super tedious thing Yeah, I've ended up writing helper scripts that I just drop it to the console to delete everything. It's Yeah, it's annoying when you get to that point. So in an effort to make matt gaunt's redundance There's now like a clear site. Well that escalated quickly There's now a clear site data button. Um, I think the label for this might might be changing The button is still there. Um, basically what this does is it almost resets the world For you, which is kind of really nice. Um, it does all the things it says above Like it will unregister your service workers new storage and clear out your cache api storage And yeah, this does seem like an obvious feature But at the same time it hasn't existed for the longest time And when you start working with service workers, you realize how quickly you just get into a mess and you just want to Reset everything and the old solution for that was to just develop an incognito windows. So this is super welcome This is this is so nice. We were talking about cache storage Because this is this is was resources panel You can still go in and debug all of your different storage mechanisms that includes the cache api So in the case of my app, I'm using um sw precache. So I have all these entries for someone like, uh Paul loose's voice memos app. We go in here and you'll just see that there's like there's an entry that's got all the different Files listed that he's got cached in the cache api. I wonder why the response is empty Shh, it's all it's all perfect. It's all perfectly perfect And you've also got other options in here like frames. Um, don't just say that like it is no one knows what frames is I I I don't know what this does anymore. It's it's basically a breakdown of different things List of assets that are down there. That's let's assume that it does that Maybe maybe this gives us something to do another episode on next week on Totally tolling mini tips. What is frames under applications tab? All right. So, uh, I feel I feel enlightened Uh, that is that is the application tab. Is there anything we're forgetting? You've got device art on the screenshot That is awesome. I've got device art. So, uh, canary dev tools now lets you like preview device art for um For a few different devices. We've got the nexus 5x in there. I think the six might also have device art It does not it does in the very very latest version I think so it's coming. I think it's coming But basically device art is awesome. Just lets you like see what it would maybe look like on an actual device And it adds in like the navigation bar at the top and yeah, so you can you can go in you can go in here and like Get your little navigation bar in Um, I have asked for us to like take the theme color into account. Oh, yeah Because you could you could do that. Yeah, that'd be really nice. And then it'll yeah Assume that by the time you've seen this, maybe we've convinced them and this is already at the date And if not raise issues then maybe we can get it Um, all right, so that that is the application tab Hopefully you'll find that a lot of this stuff makes it a lot easier to Develop and debug your progressive web apps. That's it from us. Thanks for listening. Bye Welcome to this supercharged tldw I'm paul if you didn't catch the live stream with me and serma last week Well, basically we built a side nav. Let me show you what we built So you've got your standard app bar here and click on this Sidebar and click on the background or you can dismiss it with a sort of drag gesture like that awesome stuff So let me show you how we built it But before we do that as usual we're going to head over to yep, you guessed it theory corner join me Hello, welcome back to theory corner. So this is what we've got. We've got our page and we've got a container element The container element is going to be the home for the side nav and the background What we're going to do first of all, we're going to put overflow hidden on this We're going to make it take up 100 width and height So it's got overflow hidden because this is going to transform out to the side and we don't want any scroll bars So we put that in place The background we're just going to transition its opacity from zero up to one and we'll set it to have a transparent black color Or semi-transparent black color in the background The other thing is this side nav We want this to slide in from the side So we need to have will change transform on it so that it gets its own layer very much like we do with the swipeable cards And then we can transform it in and out. We're also going to need some Buttons for bringing it in and out. We're going to have to have some touch events so that we can do the dragging stuff All cool. Let's go back to reality Welcome back to reality. Oh, yes Yes, reality. That's where you'll find us today Pragmatic to the end code Okay, so the markup and the css is pretty much what we discussed in theory corner We've gotten aside We've got a few js classes here so that we can pick it up in the javascript But mostly it's pretty much what you'd expect. There's a button for closing. There's a button for opening We've got a title here for the side nav and then we've got the list of the side nav content In terms of the css. Here's what we've got for the background You see it's actually done with a before sudo element and you can see that it's got a background of black with an opacity of 0.4 We switched on will change opacity because we know we're going to be changing the opacity. So we're going to say will change opacity Didn't say will change pasty That would be a different thing entirely Will change opacity and then we can set a transition of opacity with that curve. That looks quite nice 0.3 seconds nice and quick Then the other thing is when we set the side nav to visible which we're going to do with some javascript And we can say to that before that we want you to fade up from a no-pastive zero to an opacity of one The same is pretty much true of the side nav itself Here it is And you see it's got a box shadow So we've got a nice little bit of shadow on the side The interesting thing is we have to transform it by in my case 102 which sounds really odd But the reason is there's that shadow and if you just transform it a hundred percent to the left You still see a little bit of shadow on the left hand side. So we just take it a little bit further solves that problem The interesting thing about the side nav itself the one that comes in from the side Is that it has a separate animatable class the reason is I want to switch that off when they're doing the drag motion And have it on when they're doing the automated transition from the side in and out So we use this class to basically say this is kind of it's doing the automatic transition Or when it's off it's going to be used for the dragging Cool the JavaScript is over here And it's the same trick as last time a bunch of event handlers that we bind on with this If you haven't seen why I do that go back and watch the swiper will cars tldw explain pretty much why I do this approach to My event handlers. You don't have to take this approach, but it works pretty well for what I'm doing So we bind all those on and you can see here. We've got the show and the hide Now here's an interesting one I actually say that if you click on the side nav the containing element the container from theory corner I want you to hide the side nav Well, that will work Kinda But then if you click on something inside the side nav Well, that's kind of weird because you clicked on something in the side nav and it's going to dismiss The way we get around that is we basically say the side nav itself That's going to hide it but any clicks inside we're going to Call this block clicks function which you can find down here And block clicks all that does is stops the propagation So it's almost like canceling the event now. You don't want to do this all the time You only want to do it when it makes sense for your app and it makes sense in my case. I think so That's all good So I think all that's really left is to just have a quick look at that drag motion Now if you remember the drag motion looks like this We can click and we can drag and if we just come away from the side a little bit and let go It dismisses the side nav. So let's see how we code that in Well, we have our on touch start here and basically because this is bound to the document I basically say if the side nav isn't open Bail don't hang around so we we we're going to call this anytime somebody hits touch start But we only want to deal with this if the side nav happens to be open And what we do very much the same kind of deal as the swipe of all cards We capture the start position and we copy that across to a current position And then in the touch move We basically figure out how far we moved and then we can apply a transform in A kind of game loop and update function, which you can see here There's the translate current mind the start and then we apply it as a transform If you've seen swipeable cards, this is all sounding very familiar I'm sure but it works and it works really well The last thing is on touch end We basically say if you've translated just a little bit to the left Hide the side nav that works out really well for us. One other little thing to note is this In terms of the on touch move by default you'll get that throttled back in chrome So you won't get them every frame unless the very first touch move event has an event prevent default on it So what we do is we calculate the translate And we say if it's less than zero as in you've started to move it We prevent the default and that means it will get all the updates from then on So there you have it. That's the side nav pretty straightforward in terms of these things But this works really well. It works at 60 frames a second even on a mobile device If you haven't caught the live stream against about an hour long It's in the description below So have a look through there and have a watch of that if you've got to spare out again It's usual kind of stuff. You see all the bugs. You see all the chat You see all the discoveries and the kind of discussion that surma and I had Don't forget to subscribe Done And I'll catch you next time if you like me like clicking on things you can go okay hit the subscribe And there's the live stream Hey folks, welcome to totally tooling tips season three come check us out We're going to be talking about progressive web apps some of the tooling around them on first visit We've got a relatively fast time to first meaningful paints module bundling accessibility Do you know what the top four things to look at when it comes to web accessibility are? Uh No, I can only think of two like only think of audio and then visual So there's visual hearing mobility and cognition the first episode will be out on April the 27th So subscribe to youtube channel check out season one and two before season three starts Which will be happening soon. We promise that season three is going to be equally as mediocre at seasons one and two Chrome 51 makes it easy to know when an element enters or exits the viewport with intersection observers You can make the sign-in process way easier with the new credential management API And you can reduce jank with passive event listeners. I'm pete lapage Let's dive in and see what's new for developers in chrome 51 Intersection observers let you know when an observed element enters or exits the browser's viewport No more jank inducing calls to get bounding client rekt or listening for scroll events To use simply create a new intersection observer Provide a callback and an options object Then tell the observer which elements to watch Boom when the element enters or exits the viewport the callback is fired Check the description below for a link to a demo browser support and more Creating remembering and typing passwords is a pain in the neck especially on mobile Chrome 51 supports the credential management API a new w3c spec that allows your site to interact with the browser's credential manager and federated account services like google and facebook improving the login experience The api has three key methods navigator credentials dot get to get the user's credentials and initiate a sign-in flow store to save the user's credentials in the credential manager And require user mediation to disable automatic sign-in There's more info about the credential management api including a demo and links to the docs below Did you know that simply adding an empty touch event handler to a page can make scrolling janky Less than 20% of touch events call prevent default canceling the scroll But because the browser doesn't know if it'll be called or not it has to wait for the javascript to finish Chrome 51 adds support for passive event listeners Allowing you to declare that an event listener won't prevent a scroll making it easier to eliminate jank These are just a few of the changes in chrome 51 for developers Check the description for more details And be sure to like and subscribe so that as soon as chrome 52 is released, you'll know what's new in chrome So here we are next to a rainy river our natural environment for working on code Yeah, and this one's going to be on dev tools. So it's dev tools rain and boats. Nothing's synthetic about this in the slightest Right. So today we're talking about responsive toolbar now for a while in dev tools We've had device mode which has been useful for like building responsive sites. This is sort of an evolution of that tooling So um, some of the new things we've added our support for this little toolbar that lets you toggle between like different mobile sizes Like medium large tablet desktop But we've also improved at device emulation. So if we switch over to nexus 5x, for example You now get a little bit of device artwork from android showing on the top and the bottom Yeah, and then they've added an extra little drop down where you can then say you want portrait with the navigation bar Which is like chrome's url bar But you can also do portrait and landscape with keyboard as well Which is kind of nice, especially if you're doing like form input just to see how it renders Nice little step up as well. That's kind of cool You also have a drop down for being able to say, you know, how much of the viewport you want to occupy for your actual device preview And we've got this little menu with a few extra options in here So one of the things that you might have tried out before is the show media queries Option super useful. It basically like parses out the media queries in your page And you can just see what your page looks like at different Different media query breakpoints. I already have some beef with this because if you try and use it as is After you've selected a device, it does nothing But if you go to the responsive mode and drop down and then click on it, then it starts working What are you talking about matt? It's all perfect. It's all perfect. No, it needs an issue Okay, you file a bug on that. Um, other things that we include in here include, um, show device pixel ratio So you can switch up your device pixel ratio settings Uh, another thing that I usually have on is network throttling So if you're building um to be resilient against like really flaky network conditions or li-fi or anything like that Network throttling can be useful to toggle on Usually you can have on like a good like 3g or 2g setting and that just means that when you're loading up your page We're going to throttle that connection and and it'll show up. It'll load up a little bit more slowly And it's kind of nice just having that there because otherwise you bury it in the network thing It's way too easy to leave it on some random setting start looking at the elements fixing other problems Um, it's nice just having it constantly there in the responsive mode You can also like let's say you're building an app like a progressive web application and you've got service worker support You can also switch on offline um to try out your service worker and just make sure it's working well offline It would be great if it was just like one button like disable internet. Yeah, just it's just the airplane icon That's all you need done. Um folks, uh, we're asking about ruler support So we've got a show rulers option there wasn't there before it's now back. Um, you can check that out for you Like rulers some of the newer stuff that we've been playing with Are the ability to trigger add to home screen? So let's say you wanted to emulate your application manifest experience You can click trigger add to home screen It'll bring up this message at the very top that says, you know add this site to your shelf to use it any time Um, you can click add and it'll bring up a little prompt that says, okay Well, what do you want to customize the name of this thing too? And the idea behind this is that it's supposed to like just emulate that add to home screen experience You get on android Yeah, and it was kind of annoying because before you'd have to do it on your phone You need something to download the manifest file and normally the reason you'd want to do that is because if there's a problem in your manifest file And chrome wasn't happy it wouldn't pass it and it's just tricky to debug to having this like Hard way of just saying go and download it and pass it is Insanely helpful when you just do it As a reminder, we also have another little panel called sensors which lets you go and emulate different sensors So like you can emulate geolocation coordinates device orientation Um, and you can decide whether or not you want to emulate touch based on your device or do you want to do force touch force enabled? um, yeah, that's about it for The responsive toolbar and the new device mode. Yeah I'm welcome to supercharge now. This is a kind of tldw last week I did a live stream with surma where we made some swappable cards Now you probably recognize swappable cards from things like google now where you just kind of take a card And you dismiss it and you actually see what I've got on screen. This is what we ended up making There you go. You see dismiss it and all that kind of good stuff Now the idea is if you've not got an hour to watch that live stream back Although if you can I would recommend it and you can find the link to that below If you can't that's exactly what this is for I want to step through the things that we learned the things that we did Um, and just so you can get an insight into what actually went into it So before we actually get started what I want to do is I want to step over to the theory corner Oh, yeah theory love theory and what we can do in theory corner is discuss what we need to do join me Welcome to theory corner. You can tell it's theory corner because there's some theory in a corner Now this is what we have. We've got the cards. You can tell it's a card because it says card The cards have will change transform on it. The idea I have here is that we want each card to be People never get that excited from my talks. So Yes Cool, how's everyone doing? Are we good? Yeah, cool. Great. Um, I was I was thinking about kind of how I was going to start this whole presentation often I'm terrible at starting presentations. So just be one But I was thinking about kind of like the structure of the entire day, right and like And progressive web apps and how we think progressive web apps fit into the overall Like kind of the way that we think developers should be building or you should be building for the web in the future And the one thing I was thinking about was Every single one of these things that we've talked about in isolation is a great thing for you to be able to kind of take home And kind of work on for instance So if you're not interested in necessarily progressive web apps right now But you want to build a great user experience for your users Then you know like Paul's talk around user experience on that side of things is great You know same with like htp2 and ssl like we want to make the web more secure We want to make the web faster on the networking side of things like all those things Individually will be a great thing for your business and your services and your sites But kind of putting them all together like we think that that's where like the the progressive kind of web app part kind of comes together And I think like what we're trying to get to with this is like this is my talk by the way like putting the progressive into progressive web apps I I kind of like I'm kind of worried about this a little bit because like there's a lot of tension between the what progressive actually means in terms of progressive web applications And one of the things I'm right there I want to talk about is that when in the research that I was doing for this talk Uh, like I was going back to when we first kind of thought about progressive web apps And when it was first kind of talked about and it was alex russell and it was on his site And it was literally a year ago to this month that you like they coined this term with his wife francis barriman Uh, you know progressive web apps and progressive open web apps and when you read the article It's really interesting right because it starts off with this whole idea of as the user uses the experience more It becomes more progressively installed on your system Which is not necessarily the same thing as like progressive enhancement is which is a very important thing That we want to kind of cover on the web There was a like we did talk about it a little bit The idea behind it is that you know when you integrate a service worker and you can start intercepting the network requests You actually, you know, you progressively enhance the network you get more speed for like essentially for free at that point I think that's actually quite an interesting way to think about it right because Like we we talked about the progressive kind of installable nature Like, you know, if you want push notifications, you don't have to install an application to be able to do that You can start to get these experiences if you want them to work offline and be resilient and available You can integrate a service worker make them work offline But you don't necessarily have to have them installed on the system right your web application your website Is just better by having these features in there But at the same time we know that progressive enhancement is important because we want these experiences to work in every single browser Like whether do you have service worker or not whether you have javascript enabled or not It's an important critical point and part of the whole progressive web app experience is that these things work everywhere And when we talked to a lot of developers around kind of what progressive web applications mean is like Hey, we got service work and we can make it work offline and everyone always asks does it work on ios? Right, it's not like does it work in opera mini or unfortunately? It's like, you know, it's great that's on chrome for android, but does it work on ios? And I think that's the wrong question that people ask it's the wrong kind of The concept that they're going to because our whole idea behind progressive web applications is that your application should work really well Everywhere it should excel when you've got the ability to use something like service worker And like the the interesting thing is like ios has got a lot of users and those users pay You know, they apparently buy a lot of things which is kind of interesting Um, but it's I think it's about 10 or 50 percent market share But like if you look at it like it's not one browser that's like hugely dominant There's lots of different browsers used by lots of different people You go to different parts of the world and towel oppenheimer's going to talk about that later Like you know different browsers like uzi mini for instance are incredibly plot Well uzi uzi browser in particular are incredibly incredibly popular And you know, we as developers are we building for them all the time? And I don't think we are building progressively across the entire platform to cater for every single type of mobile user That's out there at the moment or desktop user and I went through this same experience, right? I went through airhorner.com like this is my site. It's it is Jake's got a very rude word about this what it looks like, but i'm not going to talk about it Uh But airhorner is a site that uh, it's a it's a simple air horn, right? It's a very kind of small concept demo about what a progressive web application should be I started off building it on desktop, right? I was like this is going to be really easy Right I can make this experience work everywhere and it's going to be instantly accessible It's going to destroy the entire app store model because like the app stores are littered with uh These kind of air horners experience was like go to the url Enter the uh, you go to the url Start using it you never need to download another app again That was my thought at least anyway and hey heard it. Who's got it? Um So like it was kind of interesting all the way I started off on desktop and then I was like Well, I can make it like chrome on android is pretty good. I can make it mobile got it working on mobile pretty well It used a bit of flexbox brilliant, right We're great And then because like webkit and blink at the time on chrome and I knew they're not too dissimilar They support web audio and all the different apis worked on ios. It was great And then I thought like uc browser is like ios at this point So I was like that's great. And then last week someone said doesn't work on uc, right? I was like Well, of course it works in uc. I made it right. I'm not like completely stupid. Anyway, you get to the page It's like that Like the really interesting thing is when you start to look at the stats is like 20 percent of the potential user base, especially on mobile Like it's like india is a massive place China is a massive place as well in terms of usage of this browser Like 20 percent of the users couldn't use my site. They couldn't even see a single thing, right? Like I just looked at the stats Uc browser users come in they bounce out pretty much straight away because it's completely useless for them Hey That's also the sign for me to get off stage as well. By the way, I haven't run over That's pretty cool. And then I was like, okay, cool. I'll see what it's like in a links browser again, right? It's like there's literally no content that button isn't the actual button for the The experience that I have like it's not the you press the air horn and it kind of downloads a wav file or something Like there's an install button that's hidden behind the scenes and it's like I just made a lot of decisions in the wrong way and the the thing I did that wasn't the greatest thing was I kind of targeted it off one api, right? It was like the audio api is a thing that I was building my experience around and for me like it like I said It's a very small application. It's not probably like any of the applications that you're building today on the web But it was it was a really bad thing for me. It's because I was like audio api has got pretty good support Um, and I'm kind of happy with that and I was like, okay, cool But then I looked at the profile of my users and it turns out like this is kind of uh I want to use dot com which is the site that I made But it's all backed by the can I use data and the idea behind it was that you choose a feature and go Okay, I want to use audio like what features do I get for free? I mean like use web audio api you might get kind of like css fonts and a whole bunch of other stuff Which I can integrate with my app and I chose this as the model for how I was going to build the experience And I think that was a really bad way of actually starting to build my site at the time Like the thing I wasn't trying to get across at this point at least anyway Is the fact that I started off with the technology. It was a demo application I started like I'm going to use the web audio api because I have this thing where you press the button And you can hold it and it air horns forever and ever and ever And I didn't actually start with the experience that I wanted to build I did actually want my site to work everywhere for every like by every single user on any different browser But I just I just made this kind of decision and like this is what I see when we're building kind of New web experiences, whether they're progressive web applications are just good web experiences if we go I want to use this experience I need service worker But you don't actually need service worker for every single experience that you want to build But when you do integrate in that you get a better experience for users who have those browsers And I think it's more about the features that you want to build into your uh Or the experience that you want to build rather than just the features So like you want to build a great mobile website like I should have in my um My experience I should have like well I'm going to back it off the audio element Which will then allow me to play in pretty much every single browser And then I just won't have all the same experience inside the inside the site So I should have started with that whole kind of experiential kind of focus rather than the The ability to actually go okay. I can do something fancy with a web audio API I haven't changed it and I think like when um By one of the things I was thinking about and when I was especially looking at uh Tao's keynote earlier on today is that the progressive web app model themselves as well is It's more of just a way of thinking about how you potentially architect and construct your applications than the necessary kind of individual different APIs behind it And I think like aliexpress is a good example They chose to go mobile only rather than kind of have a complete desktop solution But they chose to pick off this kind of tactical battle first, right? And I think that's a good experience where they followed the kind of progressive web app model And then they found out that all their users benefited because they were building a good web experience That just so happened to be work even better in the browser that support service worker Whether it's firefox samsung or whether it's chrome as well Uh and soon to be edging a bunch of other ones I suppose But like that's the thing is like the They got more users coming through spending more money and a whole bunch of other stuff because they built a good web experience That was kind of in theory kind of progressive from the start rather than just focusing on Hey, this experience is a progressive web app that needs to use a service worker and go from there Which I think is the wrong way of looking at it and they did the right thing So I I think I'm probably preaching to the choir at this point But like the interesting thing for me when I speak to a lot of people is understanding what progressive means and the dictionary definition And I've got it exactly what it is here is like developing in stages Right, it's like the idea of you can do things in multiple steps and build on top of them as you go along Which is a decent way of thinking about like progressive web development as a whole Now the the way that we kind of start to think or the way I least start to think about breaking it down is like I do want these experiences to work in every browser Sometimes as a pragmatic developer I have to target different kinds of experiences to different developers or different browsers at least But my whole kind of fundamental thing is I want to get the experience out to as many people as possible and not block on You know whatever browser the user is using because in most cases the things that I'm building shouldn't be blocked on the fact that You know an api doesn't support web audio because audio can be played on the web. It's a good example Now again with the air horner example, I didn't do the incremental approach to the api's right I just relied on web audio api in this case and if I was thinking about it again I'd probably go back from the start And then whether you have the diverse set of users like the importance behind why you would do progressive enhancement is because you have Users from all over the globe and tell we'll talk about this later All over the globe using every single different type of browser that you can possibly think of So you have to build these experiences catering for the fact that you have a potentially wide and diverse set of users Now there is this kind of you've probably seen this before in the past There's an illustration by Dave stew at least anyway, but like the core fundamental tenant from the progressive side of things Is you make sure you get the content and deliver it to the user Then you have the presentation kind of wrapped around it and like there's the kind of this the proper definition is around kind of adding in css and then job script on top or css to kind of Like improve the presentation layer and then job script on top of that to actually make it kind of a little bit more functional And maybe a little bit more interactive at the time But I think the important thing from from our side of things is like not every experience can Like has a lot of content in right like not every single site that you build like air horners Not got a huge amount of content, but I still built it wrong But this is one thing that we built in 2014 we as in our broader team on dev realm like sam thurgood and eric badlman In australia and america built this kind of the santa tracker experience And it's a great experience right millions and millions of users use it all the time and they get a great experience out of it But I want to talk about one specific kind of individual piece about it in terms of One of the good things about santa tracker is that you can say well, where is santa in the world right? You sit there and go okay santa is in iceland and I live in scotland right? He's not that far away. I need to get the bed in theory with the kids at least anyway Um so Something exists by the way in case anyone's watching uh So the idea behind this is like we have this idea of like you want we we as the developers of this piece of the software We want to know where the user is so that we can provide some kind of level of interaction to the user And obviously we chose geolocation api because the geolocation api gives us Pretty much exactly where the user is based off their current gps location Whether it's on the wi-fi cell towers or kind of satellites and a whole bunch of other stuff It's a really powerful api But the problem is like not everyone actually accepts it So you don't get a whole bunch of usage off the back of that and this is sorry i jumped a slide forward In 2014 like this was our entire experience. We had Like you go well, what actually what happened is you go to the page and say where do you where are you? And then people will either accept the permission with pretty much no context or reject it It turns out when you prompt the user, you know, hey, where are you? They're like, I'm not gonna tell you I am why like you didn't give me any context about why you need this So we had this experience where a whole bunch of users didn't get the the full rich experience of like the sander tracker experience Because they they disabled the geolocation never used it or you know, they didn't have the geolocation api even available in their browser And like we found that we didn't have a great accept rate for like using that one particular feature in 2015 Like it was changed up a little bit, right? It's like we know that the gps can give you a really accurate information about where the user is But like we want to provide this great experience and there are different ways that we can do that We can have no experience at all, which is like the kind of this is like the progressive way at least in theory in my head Like you have no experience at all Then you ask for you basically use the ip address to get the geolocation And then if you can do some of the things like if you know that the user's language is in japanese Then there's a good chance that they might be in japan if you can't get the geo information But then you can tie the two pieces together to actually say like hey, you're in japan and like santa's not too far away But then if you really want and you want to provide a super accurate piece of information Then you can ask and kind of say hey, we we know kind of you're in japan Do you want to find out exactly where santa clause is give them some context and then they can use the api But the fundamental thing here is that we've still as a browser developer or not a browser developer as a developer of this piece of software We still roughly know where the user might be by saying, okay We're going to use the existing information that we have and I think that's one kind of small form of like the progressive experience Is you start from no experience at all and then use all the different pieces of information that you can get Before using the more complex apis So I think the the the critical thing I want to try and get across in this bit Is that you probably want to know and kind of tactically think about how you're going to use the different apis When to upgrade the user to the different experiences and some of the reasons why you want to do that is because Not because the api doesn't exist is because it's behind like a permission or a privilege that says the user has to go Okay, you know if you want access to geolocation or you want access to the camera Like you have to ask the user the user says no like what do you do at this point? And if you've built progressively you don't have to retrospectively go Okay, cool. I'm going to add the file element in which lets you kind of pick from the camera You're just going to provide that experience up front and kind of just smooth that your development model at least So that's kind of my rough introduction. We have 50 minutes. It's pretty long What some of the things we're going to cover is that our progressive web app model covers multiple different stages of like how you think You know building your Software but like around the app shell like how you construct your application But also some of the different technologies as well that you can use if you want inside your app Inside your app whether it's push Install for add to home screen or make kind of making yourself your piece of software a lot more resilient to network connectivity issues So like these are some of the core tendons of what we think like a progressive web app might take might take And i'm going to kind of briefly cover some strategies about what you can do The first is the app shell right like what most people don't understand is that well when you're thinking about it is The html is an imperative language, right? It takes it's an ordered sequence of elements This is without css at least anyway It's an ordered sequence of elements that are executed from start to top and then they construct your document based off the back of that I think that's actually pretty cool because if you look at kind of procedural languages as well Where you can have functions and a whole bunch of other stuff that they get a lot more complex But you know html by itself is an actual imperative language now The The like this if you take your like i'm skip the page. That's why Clickers Okay, cool. So this is like a rough case study right this is it's a very simple blog Right, it's not really contextually relevant to a lot of experiences that you're building But the idea behind this like if you've ever gone to like the google blog site from the ages and ages ago Like you had to have a whole bunch of JavaScript just to be able to run a bunch of content It was just a nuts experience Um, but the idea behind this is like there's a very simple site It's created from normal simple html on job or html in this case Just render from the server and pushed out to your site Now one of the things that we've seen in the kind of the broader web industry is that a lot of developers are building sites Where you have the app shell like this is like kind of this the app shell model Like a lot of people have been doing this for a long time with other frameworks and just normally in like whether it's angular or Ember and a whole bunch of other ones So you you construct the like the shell of your application and dynamically load via ajax content in Like this model works really well, right? We can build some great experiences like gmail is pretty much built this way Lots of other different applications are built this way where you load the structure of the application and pull the content in But like Paul Lewis has done this kind of nice tweet a while ago where you kind of like Like ripped apart the different problems that you have when you're building these experiences when you're trying to build a fast experience At least anyway is that we'll get given the html right like the browser will download the html We had all the content before But now we haven't got the content Which means we can't really put on to this on the page until all the javascript is downloaded The frameworks are booted up the java in the javascript and css are downloaded and kind of done all the layouts that they needed to do So you have this massive gap between having html available Fetching some data and then actually having something rendered on the screen And like I said like this is like the like what we think of today is the the app shell model And this is one of the ways that we're asking developers to build applications is using the application shell We know the application shell works really really well for building certain types of for building different types of experiences But it's not necessarily the only way that you'd want to build a progressive web application But it's an interesting model because one of the things that you can do Is that you can focus on your content get your you know get everything out as a rendered So you can focus on your content at least with the app shell model get your content out rendered in that first request And then like you've probably been doing in a lot of applications is then start to incrementally take over the experience So this is just a simple thing where you know if you click on the link inside your application You'll So if you click on a link inside your application, you'll go normally navigate to a different url Now that's good, but inside like that whole kind of white page refresh model Is something that which is a detraction I get detraction from the user experience, especially in the kind of the web versus app world So what you normally do and you're probably all familiar with this is that you intercept the click Then go i'm going to load some content and then check that content back in that's a perfectly reasonable way of doing it But one of the things that we're trying to look at to the Right now is that We want you to think about the you do the page load so you get the content out You're still using the app shell model where you incrementally take that over and if Like sadly said, sorry, I'll go back one slide if you think about this model where you kind of intercept the content Or it's intercept the link click and load the content you've probably been doing this already in the past Which is quite a good thing because when you go to this kind of progressive model We still want you to go and do that, right? So if you have a service worker behind the scenes intercepting all the requests and kind of loading the content You have a number of different choices about how you serve that you can still do the incremental load So you can basically say not the incremental load So you can still get the html pass it as you go through render on the server And if you watch jeff's talking a little bit he's going to dive into that kind of universal kind of JavaScript Render inside of things where you can render on the server And push out to the content But we're doing that progressive render the web has got 20 years of being able to kind of progressively Like progressively render content To the browser We shouldn't kind of just throw that away because we want to get to that nice model of App shell and then load the content in we definitely do encourage you to Think about the app shell model Render the content with it and then start to kind of tactically replace that like once you know that you're inside The browser you can do a bunch of different things with the service worker You can fetch Jason data endpoints and kind of have them cashed and pulled through or you can just keep doing kind of full on page Request server rendering push it out and then kind of pass out the content and load load it There's lots of different models And I think this kind of progressive rendering approach at least anyway And the flexibility that you get with service workers helps So the thing I do want to say is like app shell is a model that we definitely know works Like it's been used for a long long time already We know it works well But there are many different tactics and strategies that you would use and I definitely encourage you to look at jake Jake archival service worker cookbook because I stole a whole bunch of his code to get my blog working Like my blog is definitely not an application, but I want that resilience from a service worker I want it to be available whenever the user goes back to it But more importantly if the user goes to any other page inside my site or refresh the page is available instantly It's not an application. It's a content delivery system In this point for me and I just chose basically a stale while revalidating method for actually kind of Fetching my content So the request comes in I'll pull the dates back from the cache always but always then go At the same time go fetch the latest content and then subsequent requests will then refresh like refresh When user refreshes the page with subsequent requests that'll load my new content because like it's already been kind of cached That worked for me in a model like as a model for kind of making my site resilient and work offline And I definitely encourage you to have a look at the different models that you can have to build an experience where You know the service worker is there to enhance the experience rather than actually say we have to push everything to an app shell The other area and I know I went talked about this a little bit earlier on is kind of push notifications Now this this whole section is We can we can talk about a little bit as well It's kind of interesting because the push notifications api is incredibly powerful It's supported across a number of browsers, but it's not on like a like on a relatively large number of different Operating systems and like it's not on ios basically at the moment And that's another question that we get is like well, I want to do push notifications But it's not on these experiences like so what do I do? Well, you know the first natural thing you want to do is you just want to check the support right? You can easily check the service worker We you checked via a service worker to see whether you can support push notifications And then you can say well, we haven't got push We just won't do anything with it But like that's the problem right is that we're not going to do anything with it There are a number of different tactics that you can use at the time So actually say we can do and give the user more compelling experiences Even if they don't have push notifications, we can keep the user up to date with important information Now there isn't like a little analogy that we've got is that Like there's like the transport kind of eco like the transfer the transport structure that you'd have in kind of any major city There's a destination that you want to get to you start a desk your point a you want to get the destination You know point b There are many different ways that you can do that You can take the tube or the metro the overground railway system or bus or bike Lots of different ways to get there But the result is the same that you know you've got that destination I think that analogy works quite well for what we like we talk about in some of these experiences at least anyway Because like there are many different ways and tactics that you can actually start to integrate these integrate different experiences The biggest thing about push notifications, uh, and this is kind of like you probably saw this from From owens talk you want to be relevant timely and accurate The the three different main areas that you want to focus on the timely bit is important Right because it's not you don't want to you want to get in contact with your user But you don't want to get in contact with the user all the time basically It's not your primary mechanism of getting in contact with the user So you want to think about how you want to use notifications notifications normally are kind of most like most relevant when you have a timely based Kind of action that has to happen You send the request to the server the user gets it and then you want the user to action it pretty much straight away So there are a number of different I can't use this There are a number of different questions that you want to ask right many businesses like I give you've already got a business or a Site there are a number of different ways that you're actually starting to think like you're already in kind of contact with your users, right? You that's right is one of my ear words. I say right Great dead powerful. So every time you hear me saying that it's me trying to think about what I'm going to say next sometimes But you have a number of different ways of actually kind of contacting your user Well, you know, you might already have their email address and you might already have like have a regular communication outbound communication with them You might already have their phone number, right? So if you have their phone number like if you have to send important relevant information You might want to send an sms system and like an sms to them And like you have other different ways via twitter and facebook I don't think those have ever really taken off in terms of private direct communication It might change when you know the the messenger ecosystem and messenger bots kind of come out a little bit more But the important thing that you have to make is like push notifications aren't the answer to everything And it doesn't matter if they're not supported in every single browser if they're supported It's great You can do really cool things with it in terms of like hey timely information You can send it to them get into action it But at the same time you can do other nice things as well So the first one is like native notifications Like like everyone knows that native notifications drive re-engagement and uses back into their experience And it's normally targeted through a single device at the same time Which is great because at most like especially in a major markets Most people are focusing on their phones at the time The current moment Now there are a number of different things that you can do where you can have contextual actions The important thing here for the native is like after that your After your site is or your application is on the user system Like having notifications is incredibly low friction and that's why we see huge amounts of re-engagement So if they already have the native app installed you might not want to actually send them push notifications But more importantly many people have email outbound proactive email communication with their users And one of the things that we see is that we don't necessarily use email in the way that we think we could use it So like you have Different way like you know who the user is like is an example Right, so you're sending an email to an already signed in user Who has already been using your system because of some important action that has happened on their site Like you know the context of when what you've sent to the user so that you can use that context in subsequent web requests We know that when a user like email is a massive driver of web traffic, you know, especially on mobile So when the user clicks on that email like you can do things like send them into the important kind of area of your site It's a really nice way of like engaging with your user Where in the past you might have used push notifications to say hey this action is really important go back into your account Use this information like because we know who you are to actually then go and complete the action Like email is still just as valuable and probably more valuable than notifications to some extent And then things like sms and like I don't think social is the right one to focus on at the moment But things like sms as well Like you can send push like they are nearly real-time push notifications They can get through to nearly any device irrespective of whether like of kind of complete network connectivity Now I think this is really important because you can embed links in there and then you can get the user to go out So if you're targeting a whole bunch of ios users who don't have things like push notifications But you know who they are and you know their phone number Then you know things like push notifications Oh, so sms are really good ways to keep engaging with your users And I know people say an sms is dying and it kind of is starting to get replaced for a lot of message apps But these type of experiences are great And then finally once you get the experience I want once you get the ability to do those ap like uh, sorry once you get the ability to Make notes make calls or sorry Refresh it once you get the ability to send notifications because you know that the device supports the ability to do it Then you need to make a decision at that point about how you treat your users Like if if you're kind of already sending the messages via sms Do you replace that experience and you have to be really careful because you don't want to bombard all your users Now re-engagement is one bit from push notifications The other bit is the the other area of re-engagement is and this is one of the really powerful areas What progressive web apps is that you have the user being able to install your experience on the home screen And when that experience is on the home screen They expect a certain number of things to happen from their side of things They expect it to be always be available and instant loading like once you're on the user's home screen You're kind of permanently on their real estate. So you have to provide the best experience And that's why I'm going to talk about the install phase at the moment Like this install step is one of those areas where We've had things like add to home screen for a long time, but it's not Worked as well as we thought so like I think in 1997 or maybe it was safari 3 at the time iOS brought us the ability to add our experiences to the home screen and steve jobs at the time said Hey, like this is the way that we think you should be building applications and experiences for our phone That you should go off and use the web platform to be able to deliver this We could make it work offline we can make it installable like the whole bunch of the things we we know history played out a little bit differently But fundamentally we've always had this ability on iOS at least to be able to get an experience onto the user's home screen And on android it was incredibly hard right like android hated the web it seems at the time They're trying to get experiences onto the home screen was nearly impossible We made it a little bit better in chrome Like there was only like seven steps rather than 12 steps to get something on the home screen But like it was still a bad experience right and that was until we started to kind of like change the whole model And like where we are now with progressive web applications and a whole bunch of other stuff Like that's like it's it's everything started to change But the really interesting thing for me anywhere in this space is that everything was controlled by meta tags There was information inside your page that would allow the browse to say hey This is how we think this is should this experience should like look and operate on the user's device um So the good thing once you could get the experience onto the home screen like you could say hey I want my application to be kind of like a full screen application Via one simple meta tag and then when the user kind of press the button It would go into the home screen you could choose whether you wanted to be a full screen experience Like a native application or like a browser experience right but the problem was it was not standardized And it was on every single page You had to kind of litter your whole site up with a whole bunch of meta tags just to get things working Even worse it was completely broken right like the whole space around this is like When you have an application or a site like you like an application You always launch into one specific point into the application like the entry point into your experience Add to home screen was bookmark this page and store it in the home screen So if you weren't on already on the home mix like the entry point into your application Like you would go into like a leaf page like imagine adding google plus I mean imagine adding google plus or anyone's home screen, but like Like imagine you're on like like one of my pages inside of google plus and you add that to home screen You don't want to keep going back to my content although i'd like it right because i write great stuff I'd like you to be able to kind of go to the entry point of google plus Add to home screen with the meta tags. You would never give you that you could never get back to the home screen It was a really hard way to manage things and then it was even broken even further from that Like if you didn't navigation inside the window rather than say hey I'm going to replace the current page with the new content that's behind this other url That is part of my application It would just go okay It's going to open a new window and the new tab it completely break you out there overall experience Um, so to kind of recognize that the other day I actually wrote it was like what can I write for this talk? And I wrote a spell on mistake as well it fixes Oh my god, that's terrible Uh, basically you have the ability to actually fix the way that ios works It means that you have to emulate a number of different things and introduce a new meta tag Called microsoft it's a microsoft meta tag ms application start url But fundamentally this polyfill essentially will say hey We know that you've got the all these meta tags in place But we want to fix the ios experience We want to make it so that it matches like opera's experience androids experience Chrome's experiences firefox experiences I've actually getting onto the home screen So it does a number of things like click jack or hide or it does click jack in so that it says Hey, we know that you're still in the experience like refresh the page content rather than redirecting you out One of the interesting things is that It's really hard to manage state on ios and this this kind of should get around it But the really great thing is until kind of ios starts supporting things like manifest then Like this is a nice model and there are a number of other people starting to think about how you can actually make The ios at the home screen experience a lot better and that's if you want compatibility right at the moment You might not actually want to say You know what ios or whatever browser it is doesn't support it and that's fine if you don't want to do it The modern way is to use the manifest and like jake talked about the manifest a little bit earlier The manifest is a way of describing what to launch how to launch it and how it should appear on the user system And when you meet all the criteria and i'm going to talk briefly about the criteria You get this let's pop up that says hey add to home screen add to home screen And you get this nice kind of installed full screen experience if you want it Now there are a number of things that we do and the whole number of different checks that we have to make sure that you don't Kind of get the prompt when you when you don't really it's not deserve it But when you you're not actually offering a great experience One of the things that we want to try and do is we want to make sure that if you launch from the home screen You get an online experience all the time like you never get the offline of source Which is why we force like we enforce the kind of service worker restriction And we need the manifest because if you're launching again into that non home screen experience Then you're not giving the users a great kind of like app like experiences Especially when it's launched from the home screen The big question is can we bring ios in line with the manifest And its own use of metatags and I think we can but I will say maximally Maximiliano furman he's done a really great blog post in the past couple of days About all the different things that you have to try and do to actually say we want to have a compatible experience There's a number of issues that you have with icons And differences between the two platforms, but there are ways to work around it But the interesting thing at least anyway is that we have all the information that we need There's a secret metatag apple mobile web app name Which kind of maps to the the manifest attributes of name and short name Obviously, we get all the icons and those type of things which is really good It's kind of nice We can say that we want to launch in standalone mode, right? We want it to launch like a native application if we don't have Apple mobile web app capable then it launches like a normal browser tab Which is another option in the display manifest We don't have complete full screen, but we have some good compatibility with the two parts of the platform And we kind of have some emulation around the theme color, right? You can say I want to get rid of the top bar by saying black translucent That's pretty nice. There are other bits which are broken like the splash screen. It doesn't work anymore Which is a bit unfortunate, but it's it was still kind of not too far off now I think that's kind of interesting But the thing that I don't want people to have to do is have to then Like work out exactly which metatags that you need to install now There are a number of different polyfills. This is the one that I've written There are a number of different ones coming through as well Where if you can basically know that you've got a web app manifest on the page You drop a small piece of javascript in and then it goes and works out what the exact best tags are to use And then it'll make sure that you offer the best kind of compatible Add to home screen experience. I think it works pretty well. This is just a demo that I've written There are another good couple of ones out there And finally and I know I'm over time at the moment is the offline section Luckily, I think Jake has covered most of the offline story that you need to kind of think about But there was one thing again is that when we talk to a lot of developers out there is like well The servers work on i work on ios and right now the answer is no and like I said before it's the wrong question to ask Right, we don't need to build experiences that absolutely rely on service worker But the thing is people still want offline as one of their core features So the first thing that they do and ask is Well, I can use apcache right like so who's built a site with apcache 20 people How was the experience? Was it a good experience? No Okay, cool I mean, there are a number of different issues with apcache I like if you were building an experience there with a like a new progressive web app Say you went away and I'm going to build a progressive web app and I need to make it work offline We still need to come up with the exact, you know case business case Why you should kind of skip the apcache section But I do think you should bypass apcache the interesting thing if you've already got a site that uses apcache and Matt's going to talk about it later You can like add a service worker in and then there will be no conflict between the two because the service worker will take over So there's a nice migration path off apcache But if you're thinking about building the experience, I would just say bypass apcache completely There's a number of different problems that it has It's hard to do good server rendering with it And then if you update you're kind of manifest and you've been to 100 different URLs Which you've kind of all kind of had cached and it like this atomic update system is going to It basically re requests every single URL. It's a bit of a nightmare to manage a lot of different problems So I would just bypass it completely. It's a decision that you have to make But I think you should do it The one thing I would say is that there are a number of different strategies that you can take You can build for resilience in the client first If you're offline and someone has a window open quite frequently They don't bother to reload it because they know there's an issue The worst thing that you can do is break the experience, right? So build for resilience inside the client handle an xhr network failures cache data locally And if you look at the firebase platform And a bunch of other ones as well They do that like they know that they can cache data locally to synchronize when there's some data connection Back in when there's some data connection that comes back And finally you can start to then layer in things like service workers and extra enhancement to give you that resilience as you need So that's my thought is I just kind of stay away from apcache at least anyway Now there are a number of different like one of the pieces of criticism that we've had is that there are a number of different Issues in terms of information and knowledge Sam Thoregood on my team has launched this always be progressive where we're trying to start to think about Hey, we have all these different pieces of technology. How can we actually get you to think about building systems which are Progressive or at least if you want to kind of polythink polyfill things through as well So we have this nice little resource We're going to keep updating it to actually give you the guidance that you need to actually build these experiences If you fundamentally require some of these features, which is quite nice One of the other things I would say is that we'd have a nice That was my killer slide. I've gone too far too far with it Is we have and we're starting to build out and flesh out our developer portal as well So on developers google.com slash web Like we want to make sure that you have all the tools that you need to build fast secure and performant experiences With a great user experience Like they're the fundamental core tenants of what we want to try and get from the web at the moment And then if you kind of start to knit all those things together We're hoping that like a good progressive web application experience that comes out the back of that as well And that's when you're kind of building in service work on this extra resilience Now the thing that I will say is that I know and every single business that we speak to They can't always completely redo their entire site And I think a lot of this is about being pragmatic You can integrate all these different components in like if you want push notifications Like that's a great thing to add into anyone's anyone's individual experience You don't have to base your entire experience off the back of that and you can provide value to A large subset of your users rather than have to think about providing the same experience to all of them But there are a number of different strategies that you can take and I think that's a really powerful way to think about it Is like you start with a good base getting the content out and delivered to the user And then think about how you can kind of enhance that experience as you go along And that was me and I know I've run out of time. So thank you very much Up next you know what I've been telling everyone you've got to introduce the next speaker Right, it's the thing that you have to do because we don't have like jaco or paul doing like the nice compare thing And I was about to walk off stage, but I'd like to introduce Matt scales I was going to talk about the tools that you can use to build these Hey everyone Okay, so hi as paul was meant to say i'm matt scales On the on google's web developer relations team And i'm here to talk to you about tools and libraries for building progressive web apps Now part of what makes progressive web apps possible now is a shift in the way that the platform itself is being developed So on the old web we got custom designed high-level features for achieving the things that w3c thought web developers wanted to do So developers want images. So we'll give them an image tag developers want to lay things out on tables So we'll have a table tag Now the new idea is this thing called the extensible web and it says that rather than building simple apis for specific things We should be getting low-level deep powerful apis that enable a much broader range of things So rather than a tag for images, let's have a tag for arbitrary graphics Rather than a tag for tables. Let's have css properties that let thing let us lay things out however we want And this is great and allows us to upgrade our pages into apps But there's this gap between the level the platform gives us and the level we'd like to work at And we can fill that gap with libraries Now in the extensible web the community is given the responsibility of providing Simple easy to use libraries to handle the specific things that developers actually want to do And this is great because it's much easier to iterate in the api of a library than it is to iterate the web platform itself And this means that even as we speak someone is out there solving hard problems so that you don't have to So today i'm going to talk about libraries and tools for service workers I'm going to talk about the new web app features in chrome dev tools And i'm also going to try and answer the question of is the thing that i built actually a progressive web app? And is there anything else i need to do? So obviously the most important new technology as far as progressive web apps concerned is service workers So just quick recap service worker is a background thread for your application that opens up new features like offline push messaging and background data sync And for the offline use case it acts as a network proxy right in the client So whenever your page requests a resource The service worker gets a chance to respond To that request it gets a chance to get in the way and do whatever it wants And also just to remind you this isn't about working offline necessarily it's about Because even being online can be a terrible experience if you have li-fi or if you just have a slow connection Maybe you're connecting to hotel wi-fi or maybe you're somewhere where data costs a lot of money What you really want is network independence You want the experience of your app to be great regardless of the network situation But in order to achieve that Complex apps are going to require pretty complex service workers There'll be a lot of code and there's a lot of new apis to learn So we're going to help with that with a library we built called service worker toolbox or s2v toolbox And this was created by by our team at google to abstract away the common patterns for connectivity independence So here's a pretty simple Example of a service worker written with service worker toolbox You import the script from wherever Wherever it's residing And that gives you a global object called toolbox that exposes the api Here we call toolbox.precache And we pass in a list of resources this says that when our service worker is installed Go ahead Fetch all these things stick them in a cache so that we know that whenever our service worker is running It has access to these resources and you use this for your app shell and perhaps any Really common small resources for it throughout your your app and then we use a toolbox.router to say to match Different behavior to different parts of our application So here we're going to set a default we're going to say that the default behavior for any route will be something called toolbox.fastest Which we'll get to in a moment And then here you can see just an example of a more specific route This is based on express js routing For anyone who's built a server in node toolbox.router.get And then there's a url pattern slash api slash followed by anything and then the behavior here will be toolbox.network first Uh, so let's talk about toolbox.fastest toolbox.network.network first So these methods are what we call strategies these are So typically you need to think pretty carefully about exactly what behavior what you want for different parts of your application So you need to choose a different strategy for each route or You know potentially Unless the toolbox comes with five built-in strategies Fastest network first cache first cache only and network only So let's go over what they are So with the fastest strategy request comes in And we race the network and the cache whichever one is going to come back first is going to return to the page So in this example the cache is going to come back first, which is probably pretty obvious Though obviously it will go to the the network will win if it wasn't in the cache in the first place Um, if and when the network ever does succeed updates the cache so the next time this happens Even if it goes to the cache, it's a slightly fresher version of the resource So this is good for stuff that you want to be fast, but is allowed to be maybe a little bit out of date Uh and just as a note because this one always uses the network if your goal is to save your user's data plan This is obviously not necessarily the best thing to do for all your resources Network first Request comes in First of all, we try the network and we give that time to succeed or fail And only if it fails do we then go to the cache? Um and return that to the page now if the network request does succeed that updates the cache Even though we're not coming from the cache this time around so that the next time we try it when we're offline or whether the network times out We get a more up-to-date cached version And so you can imagine like fastest and network first are good for slightly different things So if you imagine a twitter client Then when you first load your application You're most your highest priority is getting stuff on screen so the user has your application Uh, so perhaps you use fastest to load the latest tweets because it's better to show old tweets than show no tweets Whereas when the user does a pull to refresh that's a pretty strong signal They actually want the freshest data so go to the network and only go from the cache If you can't use the network There's an important extra option to this one because it turns out that on mobile devices that network timeout can be two minutes So if you have li-fi and your network your device is absolutely convinced it has a connection But it doesn't really then you can uh have some sort of action and it can be two minutes before you even decide to try the cache So we added an option for the network first Uh strategy that lets you say Give a more reasonable timeout. So here we're saying after five seconds I don't care about what's on the network. I'd rather show something Uh cache first um go to the cache only if it's not there. Do we go to the network? Sort of the opposite of network first Um again the network will update the cache But the one of the important things to realize here is that once that network request has succeeded once It will be in the cache and so the cache will be consulted every time and it will never be updated Um, so this is still pretty good for some cases if you have versioned URLs If you have some resource where the url will change whenever the content changes This will work fine for that And this might be for things that are uh That you want to be able to cache the things that don't change but aren't part of your application shell So the example I've been using is uh blog posts You don't want to download 10 years with a blog post the very first time someone comes to your blog But if they have been to your site and downloaded a few posts, it's reasonable to uh keep them around Cache only so this is uh go to the cache and if it doesn't if it's not in the cache fail Um, this is good for the stuff that you pre-cached because you know it's there And then network only go to the network and if it fails it fails This is what you got without service worker And the only real reason to use this is that if you've overridden the default with something like toolbox.fastest This allows you to go back to the original behavior just for one route And if those don't do everything you need to do you can also define your own strategies So here we have a uh A function i've created called fallbackish image. So What this does is it takes a request And it will try and fetch that request from the network And if it fails it will respond from the cache, but it won't try and respond with that A cache of that specific request it will always respond with this fallback dot jpeg So you can use this for example if you have hundreds of profile images on a page somewhere Perhaps it's not actually that important to have that in your offline experience. You don't want to fill the user's device with those images Um, so you have a single image that uses a fallback instead And to make this useful you have to make sure you've precached the fallback image And then set up a route that actually uses it. Uh, so it's just the same as before except instead of using toolbox dot whatever We've used a fallback image And finally on toolbox, uh, you you can get fine control of the cache as well So by default when you call precache or when you use, uh, cache only or fastest or whatever The cache that it uses is shared Over everything in your whole application. It's a default cache that sdo toolbox creates for you And you can on an ad hoc basis say for this route I want to use a different cache for whatever reason so here We've passed in an option called cache and we've set a name So that it will be a different named cache that it uses and now we can set options on that cache So that this cache can only have up to 500 entries And entries can only be in there for up to five days And sdo toolbox will go in and clean up periodically Now something we've kind of glossed over there with sdo toolbox is that that precaching step is actually trickier than it looks there There are a few problems One is that in order to get a new install event You need to change the service worker script not something that service worker script imports But the actual original service worker script so you have to remember to actually update that every time you update Every time you do a release that changes some of the resources Even if the service worker itself the logic doesn't need to change Another problem is that when that uh when the install event happens sdo toolbox will take all those resources And just download them all again even if none of them have actually changed And then you also have to maintain a list of which resources need to be precached It'd be quite easy to miss something out of that array And then find that in your next release your offline experience is slightly broken because a file didn't make it into that So we created a tool to help with this called sdo precache Now what this does is it takes a few simple options and it writes a service worker for you It's something you can stick in your build step You tell it which files you want to cache It will take a hash of each file along with the file name and write those directly into the service worker So if any of your resources change the hash will change the service worker itself will change and you'll get a new install It also means that when that install event fires The service worker has a list of every resource with its hash So it can compare it to what it already has and only download things that have changed or are new Now this can be used as a command line tool uh installable via node Um, and then you call s to run the sdo precache And here's the the simplest um option setup you say where the root of your application is and it will just precache everything in that folder You can also use it as a node module so you require an sdo precache you call precache dot write You say which service worker file you want to write and then you can pass in some options So here we've said we're going to use this glob pattern To say which static files we actually want to cache And if you're wondering whether that means that we're now lost the ability to do that dynamic Caching that sdo toolbox gave us there are actually two ways to bring it back The first is with this runtime caching option You pass in an array of objects which Specify those routing rules that you had in sdo toolbox So you have the url pattern and then you have which which strategy to use And you can even pass in options. So we have the network timeout seconds option Um, and this is great for most simple cases, particularly if you're only using the built-in strategies And if you want to do something a bit more fancy if you want a bit more control You can just say that you want to import a service worker script that you've written yourself So you could let sdo precache handle all of the static resources for your app shell And then do the dynamic caching using a service worker toolbox script that you wrote yourself And it will inline that into your service worker And this also allows you to add in things like push notifications and background sync into sdo precaches service worker as well Now service worker doesn't work everywhere as paul said and serve and appcache does So Just to reiterate should i use appcache and a new project? No, because it's terrible and doesn't do what you want and the more you can talk your application to try and fit appcache The more you find that it's still not going to work and you have to contour it even more And it has security problems and is just it's generally bad Can't stress that enough However, if you've already got an appcache for your application We have a tool that will help you transition. So sw appcache behavior is this little library we've created What it does is you you import the library Into a service worker script This would be could be your entire service worker script if you wanted You create a fetch handler and you just say in that fetch handler I want to respond with whatever the legacy appcache behavior would be Essentially What this will do is it will get your appcache manifest Pause it work out what the correct thing to do for an appcache would be and then do that But it also allows you to get around some of the security issues and some of the things like Never getting into a state where the appcache is never updated service worker won't actually allow you to do that Now sw appcache behavior is just one of a set of things that we're hoping there were that were Releasing as part of our sw helpers repo As an example of something else we're doing there's offline analytics So this was written for last year's google.io website and Was used again this year What this does is you set up a route for any analytics requests that uses that The strategy function that's provided by the library And whenever one of those analytics requests fails It will stash it away somewhere queue it up And then when the user comes back online again, it will replay it and add a parameter so that it Correctly attributes the event to the correct the time actually happened And we're hoping to add many more things to this repo over the next coming months So that was service worker. What are the tools? What are the things that can we help with? So no talk about developer tools is going to be complete without talking about chromes developer tools And there are some great new progressive web app features coming In the next release So almost all of this is only available from chrome 52, which is currently in beta But it's moving towards stable in a few weeks So first up the application panel has been renamed Sorry, the resource panel has been renamed to application to better reflect that this is now where you go to look at things to do with a web app This first panel is It allows you to debug your manifest So it lists what the browser has as detected as the name of the application what icons to use what theme color to use What the start URL is things like that and also gives you this add to home screen Button that allows you to trigger the on before install prompt So you can test code to do with delaying the install prompt Service worker panel has been redesigned To hopefully be a lot clearer The all of the service workers for the current application will be shown in a list Which I should probably have got a screenshot of But it will be less confusing about which one's active and what you can actually do to each of those service workers It has all of the same features that it did before but it has some extra ones too So at the top here, there are these three check boxes Offline is a shortcut to the same thing in the network panel that says you want the network condition to be offline So that allows great for testing the offline Behavior of your application and to make sure that your service worker is working correctly Update on reload means that whenever the The origin is refreshed it will check for a new service worker and potentially do an install if it's changed Do the whole service worker install dance Regardless of how long it has been since it last checked And bypass for network says that the service worker should load The install and activate events should happen It should still be called for push and background sync, but the fetch event should never be fired Whenever any request comes in it should not it should not try the service worker to resolve it And this is good if you've got your save and refresh workflow going on For a resource that would be cached for a long time by service worker allows you to just To go back to your normal workflow in development the clear storage panel So as a consumer of chrome, you've probably seen the feature of clear private browsing data No, that was you to get rid of cookies and things like that For a period of time you say I want to get rid of cookie private browsing data from a day ago Last week or forever was this is a bit more developer oriented This is for the current origin only I would like to clear these things and the options that it gives you are things like service worker cash Index db and things like that that a developer might be more interested in And I also want to call out a feature that's actually been there a while but people don't necessarily know about Which is down here is this cache storage viewer That lets you see what things are actually in the The cache api cache that you're using with your service worker So this can help you debug issues with precaching or When a request is failing for something you think should be in the cache So finally I was going to talk about the The question of is my thing actually a progressive web app Now I don't think we can really answer that question because it's a bit of an open question But we can try and get a bit further there One of the things that we call here is if we had a button we could click that would just like Tell me is is it a progressive web app? Am I there yet? So the chrome team built one and we called it lighthouse This is both a chrome extension and a node-based command line tool Which has a whole bunch of different tests in it That it runs on your site and gives you advice on things that you might be missing And it also has this very cool professional looking logo So as a chrome extension you load up your page You click the button And then it will reload the page a few times connect with the The remote debugging protocol Gather a whole bunch of metrics and then spit out this report It'll give you a score Which you Which will give you a vague idea of what it thinks of your your application And it will tell you anywhere that it thinks that you might have missed something And also has this best practices section that is things that it's not going to score you on Maybe you don't actually need to do these things, but if you do you should check on them It just gives you a bit of a guide You can also run it as a command line tool Just for anyone who's thinking of typing in URLs they see on the screen air hona.com makes a noise Give this talk at io and about 30 seconds after this slide came up, so it was like From the audience So you run it on the command line and it will output By default the output pretty printed to the console But you can also output jason that you can pause yourself Or the same html that the extension gives you And it's also requireable as a node module So you can say Lighthouse and then the url and then that returns a promise which results with the jason that you would have got From the command line tool and obviously the cli and node module Ways are both good ways of adding lighthouse to your regular tests or continuous integration I'd like to draw attention to the big alpha in the corner here I just want to be clear that this is early stages. None of the rules are final I'm sure there's a lot of discussion to be had about what the rules say and whether they're good rules If you would like to contribute to that discussion or better yet contribute pull requests You can find us on github And I'd also like to point out that this currently only works in chrome 52 plus, which is currently in beta So to recap progressive web applications are made possible by the extensible web They're made practical by libraries and tools There are a whole bunch of service worker libraries out there from google and from others with more coming Chrome dev tools is awesome as always And lighthouse Attempts to tell you when you're done. It's probably a bit too definite in this slide Okay, thank you very much. I hope that was useful And now jeff is going to come up Show you how to use some of these tools to turn your existing web app into a progressive web app. Thank you Everybody just bear with me a second as I switch laptops We're switched and there we are so thanks matt and Hey folks, my name is jeff posnick and i'm a member of the web developer relations team at google So As you've heard um you can go on a journey So everybody who's watching this either in person or watching via the live stream We care about building truly progressive web apps And the thing is many of us have put time and effort into our current projects So building a progressive web app doesn't mean starting from scratch there as developers what we need is a device And about like areas from improvement and different like tactical fixes That we could apply to our existing code base And in that spirit let's set sail on a journey together And what we're going to do is little by little we're going to transition an existing single page web app into a progressive web app All right, so this is our starting point We've got this web app Something I put together it uses the iFixit API to access repair guides. Okay pretty straightforward Um the initial implementation Is a single page web app that uses client side rendering Okay, and while this project uses react The concepts we're going to talk about really apply to any framework or vanilla javascript. It just so happens I was using react for this project So, uh, let's take a quick look at the initial experience of running this in let's say firefox Let me just confirm. I have my static dev server running right now Go up here Put open Okay, see some repair guides Click around a bit You know, it's it's all doing some client side rendering You know, maybe not the fastest in the world, but it works you could view your content Um, let's take a look at something else. Let's take a look at what the experience is in Safari and this happens to be safari with javascript disabled Some users have javascript disabled some users aren't browsers that don't support javascript. Um, You know, this this is an issue And this is what they say for a single page web app not great Um, and you know, again, this is a function of being client side rendered and relying on javascript So Let's see We could do now that we have a feel for what the app does. Let's try to figure out how we can improve on the current implementation And what we're going to do is use that tool that Matt just talked about called lighthouse to automate a whole suite of diagnostic tests covering areas important for progressive web apps So what we're doing right now at our starting point is kind of running into establish a baseline And it's going to give us an idea of what's working well and areas that we can improve So we're going to start the test via a chrome extension in this case But you know as mentioned, there's also this command line tool that has the same functionality if you prefer that And the tests are actually really cool. They use the chrome debugging protocol And they simulate a host of different real world conditions to see how your web app actually responds So let me pull that up Do this in chrome canary I am kind of old school and just like doing everything in incognito windows whenever i'm working with anything so Let's get our current version loaded The lighthouse is ready to go over here and we could generate a report and you can actually see it's Doing its Job it's using like the dev tools ability to simulate this viewport widths of different things and all sorts of other stuff and We can get our scores. Hopefully this is big enough for folks to read You know and we're at 30 out of 100 Okay, um, you know, it's giving us some nos here and it's giving us some things that might be areas where we can improve Service workers not there Meaningful pain times not great. You know, we have this missing Content when scripts are not available. We have a bunch of other things that we could improve So, you know, the main thing is that we have a really good starting point. We know What we need to focus on Before we really dive into the results and interpreting them. Uh, I just want to make this point then Lighthouse will help us identify areas improvement, but it's not our end destination You know, it's not the ultimate source of truth as to whether something is or is not a progressive web app Ultimately, you know, what matters is the experience that your web app provides to your entire user community So in addition to running the lighthouse to test what we're going to do Is try web apps across a wide range of browsers operating systems and different network conditions And you know, I recommend that everybody does that as part of their normal testing and release process Don't just rely on lighthouse Sorry, so we have those results here are opportunities for improvement Um, you know, our speed scores could be better and there's no counterfeit on our page when javascript is disabled And what we can do for both of those is introduce server side rendering Uh, second, it looks like our web app won't respond to it offline. So no surprise. We could add in a service worker And you know, finally, there's missing metadata about our application as per the lighthouse report And that could all be addressed by adding in a web app manifest And also adding in thoughtfully chosen meta tags to accompany that So we've got three concrete steps we can take and we're going to walk through them each now Using lighthouse and cross browser testing to measure how effective our work is as we go All right, so let's first look into server side rendering what that's what that's all about Um, you know, what it's going to mean is that our browser gets a fully populated functional page As part of the initial a should be response rather than relying on multiple requests to get content on the screen And equally important it means that our web app will work in browsers in which javascript is unsupported or just switched off entirely So not every web app is going to be able to run with full fidelity with javascript disabled But you know in our case we should be fine It's a fairly straightforward to add in server side rendering to our react application using a universal javascript And that means that we get to share a lot of code between the client and the server. So not too much work Um, and we're going to use express which is a node based web server and it plays really nicely with the react router So while we're talking about react now again Other frameworks like angular and ember have their own solutions for server render javascript. So definitely check those out as well If you happen to use those All right, so let's take a look at the actual changes that we're going to make in order to implement that So I happen to have a handy Um github diff open. So this is the real code and make this a little bit bigger So folks you'd say and just scrolling up a bit um Not too much that it should surprise most folks have done this sort of thing before You know we're adding in a serve task that's going to bring up our server and You scroll down a little bit this stuff is important, but we can't really focus on it right now what i'm going to scroll down to is um The part that actually implements like our routing and figuring out what to return to the client And this is very lightly adapted based on kind of like the react router canonical example so You know what we're going to do is just take our existing routes So we're already using on the client side and we're going to match against those with the incoming request URL on the server We have a few things to handle different error conditions and um What we're then going to do is just make the requests the ifixit api From the server It's going to figure out what data we need and the server is going to make those requests and Provide it to the client immediately without the client having to get anything else And we have a little bit of code down here once all the data fetching is complete. We just have our initial Uh component that we're going to then kind of render to string using this react dom server helper method and we are going to also take all that initial state that we have on the server and Turn it into something that's serialized that we can then deserialize on the client and kind of just have a nice Experience where the client takes over once that initial payload comes down And finally just a pretty straightforward um index uh template that just has placeholders for like a state and for the react HTML and that's the right thing All right, so that is what's changed in the step And All right, so what we're going to actually now do is run that new code And confirm make sure that our changes have the effect that we wanted in both in lighthouse and in actual browsers All right, so let me just switch back over here And It's not really live coding, but it's kind of close. So we're going to actually run our build process again Um get to see that'll go and our new server is going to start up. Um and this time We're going to be on ports 8080 Once that's done So, okay, let me just start this up again and we'll test again firefox Things look good. You know, it behaves the way we want it to behave That's great. We didn't break anything at least But let's actually go So that safari that has uh javascript disabled still and see what the experience is like there And we actually have content this time. So that's great. Um, it's a net win for those users We click around a little bit And see, you know, it's not the same smooth transitions and other things you get if you did have javascript enabled But you know, we're building an application to view this content and our users Subset of our user population can now view it. So, you know, we should definitely consider that win All right, and let's also go And rerun lighthouse should just Close this down start this up again Generate another report and you know, hopefully we'll actually be able to You know assign a number and and measure some of the impacts that that chain had change had and see in our lighthouse results Okay, so, you know, we're at 30 out of 100 we're up to 44 out of 100 is progress um And you know, most importantly, we see the changes where we kind of expected to like we have our Page contains some content when scripts are not available is now a yes So that's a win. Um, you know, we actually also see an improvement in The performance. It's actually, you know, the page load performance as fast test is actually pretty significantly better um, you know, we were going from 2.4 seconds down to you know 647 milliseconds for the first meaningful pain So, you know service side rendering was a win for that. So we're in the right direction That all is cool All right. So next up Let's try adding a service worker to address some of the lighthouse feedback about speed and offline functionality So first important reminder I've heard a lot today We need to treat service worker as a progressive enhancement Not all browsers support service workers yet And you know, we want to be careful that we don't do anything to degrade the experience on browsers that don't support it And it's also important to keep in mind even in browsers that do support service workers The very first time your users visit your page the service worker won't be installed yet So having a good experience, you know for that case is super important All right with that out of the way What we're going to do is use that app shell plus dynamic content model that's been Mentioned a few times and you know, this is something that happens to work really well with single page Applications we're starting with a single page application. It's kind of natural to adopt it in this particular case um, and what it's going to do is take the shell which is all the local HTML javascript and css that we need to render kind of like the outline of our application And make sure that it gets loaded directly from the cache whenever possible And completely bypassing the network And taking the network out of the critical path for getting things on the screen is the surest way to get consistent fast performance So that's super important And what we're next going to do is take a runtime caching strategy to handle the requests for our dynamic Excuse me dynamic content. Um, you know in our case this is coming from the iFixit API So it's going to populate that after the shell is loaded And under the hood not surprisingly we're going to use a tool That match is talked about called swp cache and it's going to generate our service worker For us and it's going to implement all the caching strategies too. So You know not too much code that we have to write in in this particular case But what we really do have to do is understand what our network traffic is and understand You know what we're actually requesting And um, you know, this is important because we have to actually set up those routes and can't just put in arbitrary URLs for that you need to know what's going on Um, you know, I always turn to the dev tools in chrome to do this. There are other Browsers that have fantastic dev tools as well But let's just go to chrome for a second now And we're going to do this again in a fresh incognito window And we open up dev tools here Let me go a little bit bigger Go to network Let's just see what happens You know, I do this all the time. This is just part of what when i'm approaching Just a new application new service worker. You really need to understand What's going on in your network because you are replacing this basically this this is crucial You have to make peace with this so you can see Some of the requests going on, you know, this is basically like our app shell stuff. This is our local css This is our local html and then starts making requests to you know in this case It's stuff from cloud front dot net and the images that are being displayed on the screen And lots of images we load in some javascript and things like that and let's click around a little bit It ends up happening not surprisingly is it makes a request the iFix API on the client this time So, you know that the initial iFix API request was made on the server, but now it's the client's taking over And it's just making requests to pull in that information About that guide So, you know, that's being pulled in more images things like that Okay, kind of have a feel for what's going on now So let's take a look at how we actually implemented the service worker in this particular case So, all right, I think This is the appropriative All right, so this is what's changed. We're pulling in You know our swp free cache library and we added a task to our build process, you know, in this particular case We're using gulp. So, you know, we're using the syntax for that But there are other ways of using sw free cache folks who really like, you know npm scripts You could put this all as a command line or read and config the adjacent You know, we're we're pretty agnostic when it comes to that and Some boilerplate, but it's kind of the interesting bits for what we're doing over here So first of all static file globs This is a bunch of patterns that match all the local static files And these are the things that kind of get requested as part of our app shell So we just need to tell sw free cache where to look and you know, if we end up adding in anything If you make any changes to our javascript if we add in extra images later on It'll just automatically be picked up as part of the build process, which is great Less for us to worry about Next, we have this dynamic url to dependencies section and this is This unfortunately a mystery to some folks. Um, it definitely could do a better job of explaining it So here's my attempt to do a better job to explaining it Um, you can You can pretty easily figure out when something that's local on disk has changed You know, if you have an image if you have css file, that's in a local directory You could just like calculate the hash it didn't figure out it's changed What we're doing is, um, you know, taking these dynamic urls These are not things that correspond to like actual html files on disk And one example of that in this case is slash shell, which is a url We're using for our app shell And you know, this is effectively server rendered. It's kind of A composite of a bunch of different things. There's some javascript. There's some css There's the actual you know underlying template for The overall structure and all of those things go into uniquely Determining what the content is for slash shell So in order to make sure that we actually have a cache that's automatically kept up to date For slash shell we need to tell sw free cache take a look at all these local files if any of them change consider that this slash shell Cache content is basically invalidated and refatch it and make sure that we have the latest So, you know, again, if you're not doing stuff that has like server side rendering It's not as important. You can get away with not doing it, but it's actually a pretty good solution for this pretty common use case And very closely related to that is the next section. Um, this kind of implements A brute force service worker routing. Um, it's kind of like Trisometric trisomorphic javascript sort of because we have like the Server that has to know about routing we have the client that has to know about routing and we also have The service worker in this case that has to know about routing Because you know once you navigate to some Random url with your initial navigation like slash guide slash one two three four five or whatever You know, that's not a real url that the service worker knows about And we don't want to just panic and give up and pass on to the server We want to say hey actually whenever you see something like that Which is a url that you don't have explicitly in the cache I would like you to fall back to this cache content Of slash shell So it's basically doing real you know brute force routing We might improve this in the future and have a little bit more flexibility, but for now We're just gonna route everything to shell And finally, um as mentioned previously you can use sw toolbox strategies for dynamic Caching within your sw pre cache config. It just kind of saves having to maintain Things in two separate places. Um, and you know, we went through the process already of looking in the network Panel and dev tools and we figured out what our dynamic traffic is. You know, we have these I fixed api requests. That's what they look like And let's use the faster standard, which is basically stale while we validate For all those and for the images Let's do something a little different. We're going to use cache first His chances are an image with the same url at this remote server is not going to change. It should be safe At least for our case And we have the dedicated cache. We're using that max entries there. Um, this is super important You know, it's something you can't actually get just with The service worker primitives right now We had to build on top of those primitives and use like index db to keep track of all the entries In your service worker cache and then allow you to you know expire the ones Once you reach that limit And definitely think about it, you know folks don't have to use service worker toolbox And i have to use free cache. You could definitely do vanilla Service workers if you want, but please keep this in mind like if you are building something and you're just caching things as you go You really do need to think about your user's cache eventually filling up so And then we just have this default Over here of network for us. Let me have a little bit more Poor little play that we add in Task and finally, you know Kind of making sure that we're only attempting to register our service worker if there actually is service worker support So, okay, so that's what's changed And let's start up Modified version at step three now and as part of This process you actually see that like the service worker generation. So sw precache will log a bunch of Output telling you what it's caching and what like the expected size of the precache You know initial payload is so See that extra output over here And our server is running again All right, so We're going to just confirm that in chrome right now. You can remember see all this This was the previous version It's fetching stuff from the network It's again kind of close things out Start fresh And in this particular case Very first time Everything is still coming from the network and you know, this is because the service worker is not in place yet so that's expected and The next time though that I end up You know reloading the page for instance Do do do Don't think that dev tools is happy right now Boo Try closing this out All right, I think chrome canary crashed Which is one of the joys of demoing things in chrome canary Let's just start that up again Open the network panel Okay, and we see our initial Stuff coming from the network. We're going to you know reload And now we see what we expect so we actually see over here from service worker So this is how we could confirm just you know visually in in dev tools that things are behaving as they should Our app shell is coming from the service worker. You could actually see the best fastest strategy in practice over here where it's Pulling in an additional copy from the network in addition to returning it from the cache So, you know, you are making a network request, but most of the stuff is just coming directly from The service worker, which is great And let's see how Lighthouse feels about that So unfortunately kind of lost our previous reports, but I think we were at like 44 out of 100 and Hopefully we're a little bit higher now All right, so we moved up a bit we're up at 59 out of 100 so we are making progress in the right direction and You know again importantly the things that we expect to have changed actually did change confirming That you know, this is not all for knots. Um, we have a registered service worker. It responds when we're offline And you know that all is great also I try to just Tempting favorite crumb in area. I'm just going to do the offline over here I'm just I can do a navigation So worked. Okay, if you trust that that actually simulates things being offline So, okay, um, definitely making progress in the right direction All right, and finally let's address the missing application metadata So these are the options that allow you to control how your web app behaves When is added to a mobile home screen primarily that's Mainly what they're used for and we'll add the metadata in both the web app manifest format and whenever Possible whenever it makes sense you use equivalent meta tags with the goal of supporting a wide range of different browsers Um, don't just set this metadata indiscriminately though Really, you know give some thought about Each of the tags and just copy things that you saw an example Um, you know, some of them have really important meanings like, um, you know, whether you're going to end up behaving like a standalone Application that hides the browsers you are all bar. Maybe that's not appropriate for your particular case. That's fine You know as a developer you get to make that decision and you could do Um, what you think is best for your users that should be the ultimate goal All right, so let's take a look at what's different We have our wonderful icon that's been added in we have our manifest Um, I am specifically on the icon. This is a little interesting. I'm actually using this utm source equals home screen Parameters part of my start URL. So if you had google analytics running For your web application, you could actually keep track of where it's been launched from Um sw pre-cache actually Knows about these parameters and will not Cause you to have to cache like a version that has slash and the version that has slash utm source He was home screen. It'll take care of that for you, which is nice And you know in our case we're using display equals standalone And here we have some Related metadata, um, we're setting theme color setting apple touch icon and we're setting this apple mobile web app capable pound sign equals yes tag And again, not everybody needs to use this exact setting All right, so let's take a look after making those changes And see what effect they add We're going to run through the build process one last time And um, you know what i'm actually going to do First is fire up Um ios safari running in like the device emulator And i want to test what that experience is like Because you know we've added some metadata that's relevant to mobile safari Let's see if it's actually doing what we want I think i have it running over here You have local host 8080 We have our basic web app cool All right, let's see what happens when you try to add it to your home screen Add a home screen All right, i mean it picked up our icon Um, you know in this particular case, we're adding to home screen from the main page So it's going to use the main page as the url Paul came in earlier talked about some interesting ways of Kind of handling the case where a user might add to home screen while you're on one of the sub pages and redirecting to make sure that it actually always takes them back to the initial page When they do launch that shortcut, but for our particular case Pretty straightforward And click on add We go over here Scroll over, you know, we have our Web app saved over there Okay, that's what we want Let's take a look At again started fresh Incognito And let's take a look um This time at that if you do application panel This all looks good. We have our metadata. We can see that's porous We can see like the actual theme color live. So everything seems pretty good Let's see if we have made lighthouse happier with us Go through the poor generation process again And I think we were at something like 60 out of 100 last time something along those lines Cool, we're up to 94. So yeah, we went from 59 Out of 100 and we had a bunch of nos over here And we have some yeses now. So that's great So You know, I think that this process Is definitely useful as Matt mentioned previously as part of like continuous integration In addition to that process and you know making sure that you didn't accidentally Have some regression that's causing like a really big drop in your lighthouse score You know, that's super important just as one additional check But okay, so we're getting to the end of this talk, but as developers our journey really is never over You know new features like constructable response streams that jake was talking about earlier for instance as a rolled out more widely present additional opportunities for enhancement And you know, I hope you'll be inspired to follow my lead though and use lighthouse to guide you towards the ultimate destination And that's a progressive web app that delights your users. You need to focus on your users All right, here's a few links. I know I'm a little short on time Definitely check those out. I'm going to just highlight in particular the progressive web app codelabs You could do them in person here for folks who are watching this via video. You could go to that URL Definitely walk you through a lot of the stuff that we talked about in this session in a hands-on way All right, so thanks everybody. Please grab me afterwards ping me on twitter if you want to chat more about the progressive web app journey And next up we have tall who's going to talk about building for billions Got some slides swapping there Hi everyone, my name is tall openheimer I'm a product manager on the chrome team and i'm here to talk to you about how you can use all the technologies That we've learned about today to make sure that your experiences can work for billions of users So when we're talking about billions of users, that's a pretty big number And that means that we really need to think about how can we reach all of our possible users And one of the really critical things here Is to figure out who your users are and to actually understand how they'll be accessing your experience and what this means Now for a lot of us we spend a lot of time thinking about what product problem we're trying to solve And who we sort of have this mental image in our head of who our user might be And for many of us this can look a lot like us based on just what you're used to and the experiences that you've had And this can lead to a perception of the world that looks something like this And now we are in amsterdam So a few of us might be thinking a little bit outside of the united states and you can throw sort of european there as well But this isn't the whole world by any means and it's definitely not your user base when you're thinking about all of the internet users So today there are roughly 3.3 billion users Using the internet around the world And if we actually drill down and look at where these users are This is a map of internet users um today by country And you'll see that while there are some users in the united states and some in europe We see much more pronounced number of users in a lot of these other areas So while the us has about 286 million internet users India has 462 million internet users and china actually has almost as much as the two of these combined With around 721 million internet users But what's really striking here is not just where the internet users are today But looking at where the growth is coming from So if you look at a snapshot over the last year You'll see that in the last year a lot of internet users came online in One very specific country and this is this is india So we saw over the last year that 108 million users came online in india alone And for india, this was actually a growth of 30 percent year over year compared to the number of users that they had before And this growth was 10 times more than the growth we saw in china in terms of absolute users And over 100 times more the growth we saw in any other country over the last year And just to put this in context This growth in india in a single year Was equal to one third of the united states entire population And that's just in one year And what's more is actually if we look at who's not yet online And where we sort of predict that the growth will be coming from We see the shift away from the united states and europe to other countries So in india you still have 864 million users not yet online the current user base There's still 65 of india's entire population Not online or over 20 times the number that's not yet online in the united states or similar areas And so this sort of question can come up How do we reach these users if we need to be sure that we're building for all of them and thinking about all of them And as i mentioned before what's really critical here is to understand your users and understand who they are So i know we've been sitting for a little while, but just with a quick show of hands How many of you remember the first time that you access the internet? Okay, looks like like most of us do now keep your hands up if that was on a mobile device Okay, we've got no hands up at this point So most of us probably access the internet for the first time on a desktop machine or maybe a laptop But when i was in india last year we spent a whole lot of time talking to internet users who Or maybe knew her to the internet or had been using it for a fair amount of time And i was sitting down with a woman who was sort of in her mid 40s We were sitting in her living room and i asked her the same question If she remembered when she accessed the internet for the first time and what device she used to access it And her answer was yes, she did remember the first time she used the internet It had been earlier that year She borrowed her husband's cell phone and accessed the internet for the very first time A few months later she got her own cell phone and was now able to regularly access the internet And so what this means is that how people are coming to your experience and interacting with it is just fundamentally different We've heard the mantra mobile first probably a number of times and for us this often means Thinking about design mobile first thinking about how our experience would work on a mobile phone But for a lot of these users how they're actually accessing with the internet isn't necessarily mobile first It's actually mobile only They haven't had an experience on the desktop or a laptop computer And they may not be using one regularly and they may not even in the coming years be using one regularly So in terms of how they'll be interacting with your experience It is only going to be on that mobile phone And so this means that you really need to think about what your experience can be like For users who may not have had experience interacting with your product on other platforms and making sure that you're still designing for that in mind But beyond just the sort of using mobile first this means that it's also really important for us to think about what the device that users are using are like So taking a look at one device. This is a device that some of us might have in our pocket This is the nexus 6p and it was released in 2015. So last year It's a it's a pretty big device 5.7 inches measured diagonally It has three gigabytes of ram and then depending on how much you want to buy and how much you feel you need It can have either 32 to 128 gigabytes of storage Now in comparison when we were in india We went to a number of stores and actually asked the shopkeepers. What device do you sell? What device do people ask for what would you recommend for me? And this is just an example of one device. This is a samsung j1 And this device was also released in 2015 It's 4.3 inches measured diagonally. So a bit smaller It has 512 megabytes of ram And four gigabytes of storage So these are two devices that were released in the same year but have very different specs We see one sixth of the ram and even in the best case scenario one eighth of the storage capacity And this means that the user is going to be accessing your experience on their mobile phone under a very different context Than the phone you might have in your pocket and the phone that you might be testing on and seeing what your experience looks like And now the difference in context goes beyond just the physical form factor of the device that they're using Because they're relying on cell phones This also means that cellular connection is their primary way of accessing the internet fairly often Now many of us are probably used to accessing wi-fi. We've connected to wi-fi here Probably sometimes complaining about its speed This isn't necessarily the case for the users and it's because you're relying on something That's in your pocket as you move and shift scenarios So does your connection to the internet and you need to keep this in mind when you're building experiences But this phenomenon is happening all over the world. We also see that in the united states 20% of us households rely only on cellular data When they're making connections to the internet and what's really interesting is that this number is actually doubled since 2013 So we're seeing this increasing So the reliance on cellular networks as your primary way of interacting with the internet is increasing across the globe And this has some consequences when you're thinking about the conditions that someone is trying to access your experience under Now we've heard a lot about sort of slower connections and the impact this can have But we see that globally about 60 of mobile connections are 2g And this is just actual 2g connections It's not necessarily talking about 2g like speeds which can actually be even larger And when we start thinking about the areas where people are coming online for the first time We see this more pronounced at about two-thirds of the connections But what's more is that while we're seeing this decreasing we're not seeing this decreasing at a very fast rate We the predictions if you sort of estimate it out is that by 2020 One fifth of the connections globally will still be 2g and again, this is still excluding those 2g like speeds So the problem of connection speed is going to persist for the foreseeable future And we've seen some stats about this before and it's sort of widely accepted that a delay in your experience has a very large impact on how users Experience your site and we've seen that a study found that in a one single second delay In your page load time can lead to 11% fewer page views or a 16% decrease in customer satisfaction if we're talking more qualitatively And so that 2g connection that might have very slow round trip times If that impacts what your experience is like for the user is likely to have a very negative impact on how happy they are with what you've built But beyond just the connection quality that is introduced by users relying very often on cellular connections Cost also starts to play more of a role here So looking at india again and doing an estimate of sort of minimum wage minimum wage in india is a little bit complex as it depends on your job role etc And looking at how expensive a data plan is With some simplifications, we see here that on average you would require 17 hours of minimum wage work in india To purchase a 500 megabyte data plan And we're all we've been thinking about the mobile web. So just to put this in context looking at sort of the average size of a web page today If a user in india receiving minimum wage were to spend that entire paycheck On just data just to access the mobile web One hour of minimum wage work would load about 15 web pages And just take a moment to think about how many web pages you visited today or even visited During the last talk or during this talk and think about how many hours you would have had to spend to be able to afford that And what this really means is that the cost of data Requires a trade-off if they use one thing it means that it's they're not using something else And they're constantly making these trade-offs to make sure that the data that they have is using the best way possible And this results in the frequency of their connectivity Really varying when data costs are so high You need to make a choice if you're going to use one thing or the other And sometimes you just want to turn it off all together One user that we spoke to actually said that on an average day They turn airplane mode on and off 12 to 15 times because when you're not using your phone And you put it to the side if data is expensive you want to make sure it's not getting used unless you find value out of it And this means that if you're trying to get a user to interact with your experience You really need to make it worth it for them because they need to be willing to pay that amount to just access that experience And so this might be a little bit daunting, right? These are a lot of different constraints and conditions under which people are accessing the internet that you may not be familiar with firsthand And so you may be posed with the question great People are using mobile only devices connections can be intermittent They can be slow and when they do exist. They're really expensive. So so what can I sort of do? And what does this mean for how I develop? So some of the the methods that we think about might be a little bit hard under some of these conditions Installs become really challenging because what you need to do here is convince a user to pay The time and data costs to install your experience Before they've even tried it out and this can be really hard when the costs are so high and the networks are slow Because it can take sometimes hours to download a single app And what's more if the device has limited storage capacity your apk size starts to be really really important You need to start to make sure that it's small so that a user doesn't have to delete photos or videos Or other apps on their phone to make space for your experience And what's more is even beyond this first step You're probably working to improve your experience Which probably means you want your user to update their app And this is again once again challenging because they need to take that extra step on that slow connection or expensive connection But you're all here. You probably all know that there's an app that solves a whole lot of this The mobile web as we know solves a lot of these things just inherently and how users interact with it Right with the with the mobile web as soon as they navigate to your experience. They see your experience They don't have to take an extra step before they try it out. They got there. They see it. They can try it out This also means that storage constraints for that initial interaction are non-existent just by virtue of finding it They can see it and start using it And it's always up to date So as you continue to make improvements on your product your users get them right out of the gate And they don't have to go take an extra step just to see the latest and greatest that you've built But as you know, we've been Uh talking a lot about the reach that this introduces And what we've seen these are some stats that we talked about last year Is that removing these barriers has a real impact on the reach that your experience can have We see that on average users navigate past 25 apps per month And this is compared to over 100 websites that a user will navigate past on chrome on android in a single month And this not only is a breadth of experiences that users pass by but has a real impact on the number of users that a single experience has So looking at the top 1000 mobile apps and the top 1000 web websites We see that on average user there is 2.5 times as many users on the mobile web As there is on these top 1000 mobile apps And what we're seeing is that mobile web is also growing at two times the rate of native apps in terms of numbers of users In these same buckets of top 1000 So really what this means is that the web inherently provides you a whole lot of reach and we've been talking a lot about today Is how you can use progressive web apps to not only leverage the reach that the web inherently has But to build experiences that really work well for you and for your users so that they highlight and have all the Capabilities that you need to build the best possible experience and for your users to get the best possible experience So i'm not going to focus on this too much because you've heard a lot of this today But progressive web apps overall not only offer a very smooth experience, but they also offer a lot of Options for how to support some of these other situations that you really need to think about when you're building for billions of users So how can you leverage progressive web apps to actually reach and build Great experiences for users around the world So the first is cost we talked about how cost can be very limiting for users to even try out your experience for the first time So i'll talk about how you can leverage progressive web apps to really remove that barrier And second is connectivity when you do interact with these sort of flaky connections How can you address that to make sure your experience is still as fast as possible? So you're not incurring that one second delay that has a huge impact on users experience And finally, how can you make sure that you're making the experience as simple as possible? And just removing as many extra steps that your users may or may not need to actually take so that things continue to be fast and efficient So to jump into the first one cost Now on chrome we've been working on addressing this issue across the board So we do have a chrome data saver This is a proxy for htp content that a user can turn on And with functionally no fidelity change users can see up to 60 data savings But we've taken this a step further because we know that cost can be very constraining for some of our users And we've actually decided that on slow connections for htp content We will automatically replace most images on the pages with placeholders We maintain things like navigation icons, etc So users can continue to load the page But at this point the user is in control of where their data goes So they can choose to load all the images on the page They can long press on a single image to load it if they need it But we're not using their data without their knowledge and without them needing it And we've seen that we were able to increase data savings to over 70 percent in some of these situations But we also know that this doesn't necessarily work for for all experiences And so there's also a number of client hints that you as a developer can use to make sure that you're optimizing the experience For the users Based on the device that they do have so with dpr width and viewport width You can make sure that you're only sending the image size that you need To the users and so that they're not incurring data costs for something they may not be using or may not actually need What's more is we've also launched a save data header And in chrome this maps directly to whether the user has that data saver had Feature turned on or not which means that you as a developer know which users are the most data sensitive And can adapt your experience accordingly and can do so in the way that works best for your product So maybe that means only loading, you know one key image that's critical for it and making the other one sort of on Demand for the user or not auto playing video or whatever it might be That makes sure that you aren't removing constraints for the users who need it most While still making sure that your experience works for them But we also know that this can be challenging and there's a lot of optimizations to go on So we also have the page speed module Which is a server side component that you can actually drop into your web server That will do a lot of these optimizations for you And if you drop this in this can do the optimizations on both http and https content With functionally no fidelity change So it's similar to that data saver feature that we have on chrome overall But you can do it on all types of content And what we've also done is we've actually gone a step further so that for the users who have data saver on We do a few extra optimizations to make sure that we're really doing as much as possible to help those users who are Feeling sort of most constrained or who have expressed interest in us saving them even more data So just to give an example of this This is an example of a store mark storefront that we built On the left you'll see a screenshot of the store with with no page speed And on on the right you'll see it with page speed Now these look really familiar and very similar if anyone can point out any differences Let me know afterwards, but they look functionally identical But there are actually differences when you dig into this So If you look at the one on the left here, uh, this is 350 kilobyte paid So it's relatively lightweight compared to the sort of the average website across the board But simulating a 2g connection this page can take over a minute to load And as we know waiting is bad. It causes a bad user experience It causes your metrics to hurt and you really want to reduce that as much as possible Now by just having the optimized for bandwidth in page speed module What we see is that we are able to actually shrink this to 165 kilobytes or about 50 fewer bytes But for users who have data saver on we and we go even further We're actually able to shrink this to 120 kilobytes And what's more is on the same simulated 2g connection We actually dropped the load time to under 30 seconds And this is functionally with no fidelity change to the user The user is seeing the same thing But you are saving them data and saving them time just by dropping this one line of code in And what we're seeing is this is just one example But we've seen that on average even for users who do not have data saver on We see about 37 data saving with no fidelity change at all But beyond just removing uh cost and decreasing cost that comes with data usage on mobile In connectivity is really important and you need to make sure that things load as quickly as possible So just to give a sense of how these things can vary based on connection types So round trip time or the time between making a request and actually getting a response varies pretty drastically between all these connection types At one extreme you often see sort of 50 milliseconds Round trip times on wi-fi. I know conferences can be different But at the other extreme you have sort of 50 times slower on an average 2g network with 2,500 milliseconds round trip times And so this can be a little bit daunting. What can you actually do about this? So the first thing you can do is downlink max actually offers you a way to know which connection type in the first place Your user is actually on when they're accessing your experience and you can subscribe to updates So if a user switches connection types you as a developer know and can make sure that you're giving them the best possible Experience and not incurring any of those delays that might otherwise happen But what can you actually do about it when you do know? Okay, my user is now on a 2g connection So we've heard a lot about service worker today Right, we know it's a client side proxy and written in javascript and you can use it to support offline and all these things But you can also use it to make sure that your experience is as past as possible So jake this morning talked about wi-fi or the experience where your phone thinks it's connected But you as a user are not actually getting anything and this can be incredibly frustrating This isn't only those sort of really flaky intermittent connections But this can also be the case when you're on a really really slow connection and the round trip times are just so large And so what you can do here is with service worker You can actually implement request timeouts to address these flaky connections So that if a user is on that really slow connection They're still getting something very very quickly and you're they're not waiting for it to load But we do know that sometimes there's no connection Right, we've seen this offline dino a lot today when we've been talking about service worker And we're really we're really trying to make sure that you all have all the tools You need to kill the offline dino and make sure that when a user goes to your experience They're never going to see this offline dinosaur But there's been a lot of interesting ways that we've seen people who have been leveraging progressive web apps address the offline situation in a way that addresses the flows that are most critical to them So just as one example, uh, this is conga conga is one of the top e-commerce sites in africa And they will actually be talking a lot more detail about what their progressive web app tomorrow And what they've done is they've built a Checkout flow that can work completely offline So for users online and add some things to their cart And then loses connectivity or goes offline or turns on airplane mode for whatever reason it might be They've actually adjusted their flow so that instead of having an online checkout flow It has sort of a call to order flow so that the user can still complete the transaction or the flow That's most critical for their product in a way that works regardless of their connectivity type So they've really taken their time to think through what is the critical use case for our users And how can we actually let them complete that use case even if they have no connection? And what's more is they've actually found that for that critical flow This has shown a lot of improvement So compared to their previous mobile website This used 84 percent less data And so addressing a lot of these speed connection issues also has a benefit of addressing some of those cost issues that we talked about earlier What's even more is that compared to their native app this new flow Actually used 82 percent less data So this has been a drastic improvement not only to their previous mobile website But also to their native app experience and again, they'll be talking a lot more about their overall Work tomorrow morning. So feel free to come to that But beyond just trying to address connectivity and cost Removing complexity is always a good thing making things easier is always just going to be better for your users And when we're talking about users that are sort of coming online for the first time Every step you're asking your user to take is time and money because on those 2g connections Every page load is just going to be sometimes minutes of waiting So if you're giving them a page load you need to make sure that that page load provides value And if it doesn't get rid of that step and there's a few ways that we can make that happen So we've talked a lot about add to home screen and how you can use this as an easy way for users to get back to your experience This can also be used as an easy way to cut out steps for your user So that users who are more engaged and have expressed interest in your site can with one tap get right into your site They don't have to take extra navigations wait those 5 10 minutes spend that data on those page loads Just to get to your experience. They can tap on it straight from their home screen But beyond that with the notifications you can also make sure to deep link them to specifically the part of your experience at the most critical times So that they're not taking extra steps even within your product experience to get them to the part that might be most relevant to them So this means that regardless of what their connection is or their their cost is you've just removed steps And they don't have to wait that extra time unless it provides value to them But one of the things we talked about is that can be really hard to try this out and make sure you understand What it's like and so there are a few tools you can use to actually test this experience directly and make sure you're testing it With a global perspective and under all of these different situations that maybe aren't what you have in your pocket or what you use on a daily basis So we do have a mini mobile device lab and it's up on github And so this will let you simulate a bunch of different devices So you don't have to go out and buy you know a million and a half devices We can make sure you're simulating your experience on all these different devices to see what users who Use devices that are very different for yours are actually experiencing But what's more is you can actually use dev tools to understand the cost of your experience So just to walk you through one thing here So we've talked a lot about dev tools, but I want to call your attention to the network piece specifically And so you'll see a button at the bottom here That actually lets you know what the what the payload of of your load was and so right now at the start It's sort of pretty light 785 if we look a little bit more into this we noticed a lot of things came from cash So probably why it was pretty light But you can actually just go ahead and hit hit refresh here And now you'll see that sort of on a fresh load. This was actually quite quite a bit heavier And so it was over 200 kilobytes And so this is just one example But you can use this as you're navigating through your experience to get a sense of like, okay How many how many megabytes is a user using if they're actually actively using my experience? But going beyond this you can also use this to understand the time and how much time users are spending on Just waiting for your page to load So you'll see the time down here right next to the the megabytes But what's more is you'll also notice that up here you can throttle it and change the The simulated network speed so that you're not relying just on your wi-fi to see what how the page load actually happens So if you'll see that if we change this to 2g This actually starts going from 600 milliseconds that we saw before To roughly 11 seconds for for just this page to load And what you can do is you and as you adapt your experience as you use service worker And now these other technologies that we've talked about you can see how this changes and make sure that you're really Optimizing for experiences and that you're building an experience that you would be happy to use If you are actually facing sort of some of these other conditions that you might not have firsthand experience with So the main idea here is that by keeping sort of three principles in mind You can make sure that the experience you're building not only leverages the reach of the web But also takes advantage of progressive web app technologies to build the best possible experience for your users across the board And we have a lot of different technologies and details about how you can apply these Not only for progressive web apps, but specifically to address the needs of billions of users online So feel free to go there for more details But the big takeaway here is that just by keeping in mind the fact that not all users who are using your experience Look like you and are accessing the experience under similar constraints You can do a whole lot to make your experience much more accessible And as a result have a much larger reach and have the potential to reach billions of users And so with all of this you can really build an experience that is built to work well for everyone And with that i'm going to hand it over to chris wilson to wrap it up for the day. Thank you very much Good evening Skip the slides ahead here Okay, so good evening. I'm chris wilson. I'm a developer advocate on the web platform at google And I have worked on the web platform for a super long time I actually just had my 23rd anniversary of working on the web platform Um, and I have to say this is one of the most exciting times In that history because progressive web apps are an amazing breakthrough in user experience Like this lets you build stuff that really just works for users And this is the first time I can actually say that and not kind of grimace a little bit inside when I say that So I hope that we filled your heads with a ton of really interesting stuff today I hope that um You know, we've given you a lot of grounding of what you can build and how you can go about getting started I hope we've impressed you with the opportunities both in market opportunities And as tal just talked about in addressing emerging markets, which I think is a really great opportunity for the web as well So in this talk I want to discuss a few areas that are still kind of under construction This isn't stuff you necessarily want to be putting into production today A couple things in here are but but most of it is sort of To spark what what's going to come next in the future So this is kind of the next next level of user experience And if you saw my google io talk Pretty recently what's next for the web you might think this is just a replay of that and it totally is not This is not a whirlwind deluge eye chart of new features I actually just want to focus on three important challenges That are relative to progressive web apps. Um first and foremost knowing who the user is a k authentication and sign on And enabling the user to pay for things on the web which would be kind of nice And finally connecting with hardware Which is kind of near and dear to my heart personally, but i'm going to talk through some developments in each one of these And starting with knowing who the user is uh sign in in particular Now let's take a look at an average sign-in screen Today like this is what users land on most of the time And they often have a lot of problems with this. I know I do because every time I go back to a service Um, I can't remember. Did I sign up with this with my google plus account? Did I use facebook? Which email address do I use did I use because I have multiple email addresses? um, all I want to do is get to the application And of course my favorite button on this entire Page is forgot password. Is there anybody here who's never used a forgot password button? Oh, you're my hero right there, okay Or you're lying which is actually Not calling you a liar, but anyhow on top of that Mobile devices which of course a lot of browsing has been moving to mobile It's really really hard to type particularly things that are not you know words in your preferred language Um, and especially when you're using different characters like you do in a password I know for example, I have optimized at least one of my passwords To have characters that are more easily accessible on a mobile device screen So I don't use till this in my passwords anymore because it's two extra taps away on an android on-screen keyboard And i'm sure you can understand this leads to a problem I'm sure some of you know what this is already so just call it out. What do you think this number is? Most commonly used password. That's right. This was the most popular password in 2015 It edged out the previously most common password password And of course, you know, this isn't even getting into how many of us share passwords across different services I mean, I mean how many of you share passwords across services because I would never do that The point though is the complexity of remembering passwords Leads users to use weak passwords or to share them and that of course is a significant security risk So chrome and pretty much every browser out there try to encourage stronger passwords by using a bunch of characteristics to automatically detect when you've signed in successfully And prompting the user to save it And then auto filling it when the user returns to the site You don't need to remember to you don't need to type anything hopefully this will just work and Chrome actually also has and several other browsers have features that will synchronize that across different devices as long as you're signed into chrome And in chrome for android this also applies to android native apps. So android native apps get the same password data But even just chrome's password manager alone assists eight billion sign-ins a month Like eight billion times during a single month is how many times that saves somebody from typing in a username and password Now to a large extent this should just work like you shouldn't have to do anything I should have stopped talking about this like three minutes ago But since this is auto detection, this is guessing It's best to give password managers hints so that they can guarantee that their password forms are being treated properly The best thing is of course that these hints actually work across all modern browsers This isn't chrome guidance that i'm giving you this just kind of works So despite this talk being mostly about what's next go do this right now Since password managers are heuristic based sometimes extracting that semantic information is difficult Just give us a hint like here. We can't really tell what the What the username is is a display name phone email So you can solve this simply by putting in autocomplete attributes username and password And if you're marking up passwords use current password Because when you have account creation or changing password forms You can use new password for where the new password is going and this has two effects I'm only mentioning this because there's one really interesting one The first boring one is simply this prevents password managers from plugging a password you already used into a new password field But when you mark up your forms with new password The browser can also tell that you're trying to generate a new password and you can do it for them Like we can we can go ahead and just auto generate a password for you So instead of a password like this You will get this Well, not exactly this. I mean don't write this down or anything Something like this like we've been experimenting with auto generating passwords in chrome for a while It's actually in chrome canary dev and beta channels Hope to deploy it to stable soon But if you properly mark up your fields with new password That'll it will make this possible. We'll be able to do this and other browsers will too But setting inside that stuff What's really next generation for sign-in is using something called the credential management api Now we've just shipped this in chrome It's still kind of early days certainly not implemented across all browsers yet But the credential management api gets you away from using form fields with wacky autocomplete Properties attached to it and lets you integrate more deeply into the sign-in process of the browser So you can also by the way Use this to sign into federated services, which is kind of hard to do in a form so AliExpress, which I think we talked about earlier is actually a really great example of a user flow because it's a shopping app It's really important for users to be signed in right away To ensure that if they have items in their cart, they're still there If they have preferences or stuff that they've been looking at or wish lists. It's already there But at the same time you really don't want to force the user to log in as the first step Like you don't want to take that active step of saying Okay, give me your username and password before I show you anything Because if they're a new user, of course, they may just want to browse or I may just be searching for something new I don't want another step in my way so With aliexpress when a user launches from the home screen It loads up this app shell and during the startup the app Asks the browser for the user's credentials if it can get them Without bothering the user And then they can sign the user in you can see this at the bottom here And they don't need to ask the user at this case in this case Now they do this In the credential manager api and the code for this flow is really pretty straightforward There's just a navigator dot credentials object and you have a get method You can ask it you pass it in some options. You say this is a password based credential And most importantly here, I want this to be unmediated I don't want to prompt the user from this call So this code is actually safe to put on every page in your app to try to trigger Sign in because it won't ever interrupt the user's flow. It won't ever pop up a dialogue It will just fail if it can't do it automatically Now auto sign in is kind of new for the web We're starting out pretty conservative So the browser will only hand over these credentials if the user is turned on automatic sign in And if this user only has one credential for the site if they have multiple credentials We don't want to pick for them. We want to make sure that they they get to choose And of course this would be an interesting security place So we need to make sure it's kept secure so credential manager api is restricted to secure contacts like many new features And passwords are never actually directly exposed Like when you do get what you get back as an object that has the password Which you can then hand a fetch to post to a same site endpoint And it has to be a same site endpoint. You can't be pushing this off to other other sites, of course So once you get these credentials when you actually want to sign in You call fetch and pass it in a post Now when automatic sign in isn't possible credential manager api can still offer a one tap login It can still say I want to sign in and then trigger a chooser dialogue So the user can enter new credentials or they can pick between multiple credentials that they have So chrome will present an account chooser like this one. This one only has one available But if you need to do this you use almost exactly the code that you saw a minute ago The only difference is there's no unmediated in this So you can use this flow when the user clearly has an intent to sign in Like if they click the login button then obviously you can run this So this is all great. You actually do need to forcibly store credentials And this is where our heuristics often fail But the credential manager api actually lets developers have the ability to choose When the save your password prompt is triggered so chrome isn't going to miss out on when the right time to to trigger this is So if the user has just entered their credentials into a form you just create a new password credential and tell it to store That constructor will deal with parsing your form pulling all the fields out that kind of stuff And you can use this as I mentioned before for doing federated login google plus facebook any other Federated login you just have to create that credential using whatever Whatever the that particular federated credential wants to use as an id and A end of provider so an identifier and then the browser kind of just deals with the rest of the process for you And finally of course We can forcibly sign you out. We can say hey, don't ever automatically sign me back in always prompt the next time that That the that you call the credential manager api to do an automatic sign in So a number of companies are already using credential manager api or Started working on it in some cases deploying this in bits of pieces in bits and pieces You can play around with these today in chrome Because we shipped this in chrome 51. So it's actually turned on already But now I want to move on and talk about paying for things Now obviously we've been able to pay for things on the web for quite a while And it's no surprise that given the rise of mobile computing A majority of commercial traffic is coming from mobile devices like this one What is surprising though is that 66 percent of purchases are actually happening from the web on mobile devices. So By and large users are using the web to purchase things more than they're using native apps to purchase things So I guess the web isn't dead after all but Unfortunately, there's a lot lower conversion rate too and conversion rate is a weird concept So I want to make sure that I sort of capture this 66 percent fewer conversions Equates to if on average You make three euros per visitor to your site Now on a mobile device you're going to make one euro per visitor on your site on average Like this is pretty bad, right? This means mobile users are not paying you as much or they're not spending as much on your site Now if you if you wonder why I think the answer is actually pretty simple Because checking out particularly on a mobile device Is still a pretty messy problem I'm pretty messy project So check out forms have improved since the beginning web commerce of course, but fundamentally It's still kind of the same thing. I still have to manually input my credit card info My billing address my shipping address. This has gotten so bad for me personally by the way I get really really excited When I go to a form and they have put the zip code first and they automatically fill out my city and state for me Like I'm so excited that they do this when if you back up for a second I shouldn't have to enter any of that like it should just know What that information is And of course this is worse on mobile devices too because you know if you thought typing your email address was bad Try typing a 16 digit credit card Especially when they forget to label the field properly and it gives you the qwerty keyboard Yeah, it's a mess So just like with sign-in our first step to solving this problem is autofill Now autofill works on existing forms. You don't have to modify your site. Although it does actually do the same kind of Same kind of autocomplete types But stores the user's address and credit card info. You can manually save this in settings yourself. You can let it auto detect it Chrome will synchronize it just like with with user sign-ins But so autofill is great. I mean it does actually improve the problem It it raises our conversion rates about 25 percent on an existing site with no changes But although autofill gets rid of the manual nature of data entry It does make it simpler for the user But it's fundamentally the same kind of existing checkout flow. You're you're still Handing the user the same form It's just they have a stamp for parts of it and they just have to make sure they end up in the right places So the web checkout process really needs to be kind of reinvented overall now Like I said before the current checkout process is really pretty form heavy For users though the ideal experience would really be the server just works it out with the browser Like the browser is your user agent Like that's why we call it a user agent. It works on your behalf So sites should be able to focus on creating an amazing and engaging shopping experience and not so much on That last set of pages that you have to navigate through that has a long checkout form So this is where web payments comes in With the payment request api so payment request is a simple javascript api It allows the browser to handle that heavy lifting of payment collection And give the user a one tap checkout But still make sure that the site is going to get the right set of information Not the wrong set of information and the user has explicitly said yes, I want to pay them this much money So this is an openly developed standard api No matter what browser platform or payment method you choose everyone should be able to pay for Pay without a checkout form In the end we're still working on this but obviously we'll come back to that This is under development in the w3c web payments working group That group's goal is to create a universal So cross browser standard for any website to accept any form of payment So this isn't a chrome only api. We want this to be supported across all browsers In fact, I really want to give a shout out to microsoft Because they've done a ton of work in the web payments group as well Some love all right and And uh Although we're targeting mobile first with chromes implementation because that's where it's most impactful Payment request is explicitly designed to not be tied to a given platform The goal really here is to create an open ecosystem where any website can Accept any form of payment with minimal code changes and without any proprietary one-off payment apis So with autofill we can eliminate that manual and tedious bit Our implementation actually uses the same data from autofill to so you won't have to enter your credit card details one more time If you've already done this And since the browser is taking care of this the steps of collecting the right set of information We go from having multiple taps multiple forms to just one. You just have to approve it So the flow here is really the site initiates a payment request The website passes to the browser what it needs for that. So it says how much is being are you charging What set of items do you need? Then the browser determines the intersection of what types of payments they They uh The site supports and what payments the user actually has what payment payment methods And then presents a selection ui to the user to choose which kind of payment app This can be anything from a simple credit card to an installed payment app like android pay And then the browser gets a response back on this and returns it to the merchant and the merchant the website the merchant's website Now has everything they need to process the payment. So credit card info or the right set of tokens So looking at this in code. I know this ends up being kind of small because it has a lot of of information on it, but the real this is by the way based on The first published working draft this may change. So like if you go back at this slide in a year It's probably not going to be totally right on but we'll see When you create a payment request, which is the first line of this All that you do is the first parameter is an array of what supported payment methods the merchant supports So here they'll take visa mastercard amex discover But that's all not any other credit cards or other payment apps or anything like that Now the default here Is that is this right it is using credit cards to pay for things because that's kind of still where we go But they also pass in the line items the set of things you're paying for whether they want shipping options So the website can actually support those shipping options and negotiate them later and then update the total price Now I did talk about payment applications Um, I wanted to describe this a little bit in a little bit more detail So google launched android pay late last year not late last year early last year And we've seen phenomenal growth in people using it to pay for things on android devices and and with merchants physical merchants But what makes this even better than using your credit card Using your credit card directly. I should say is that it uses a tokenized version of your card when it passes it to the merchant So they can't reuse your card information And of course it uses device authentication to protect your transaction. It knows it's using your phone It's not just a number a credit card number So Let's take a look at android pay All that you really do is you have the same payment request creation, but you give it a different supported type a different supported payment method And here of course android pay has some app specific parameters. So it tells you What gateway it's going to use what key it wants you to use what version of the api And of course that would be different for different types different payment apps So you can get started with this today. It actually is supported But it's in dev and beta builds of chrome for android. It's behind a flag until we launch late this year Um, and then we plan to add more platforms including desktop and the ability for third party payment So other payment applications um to register with chrome in 2017 So we've been working with a large set of partners on this. They've been testing this kind of improving it I explicitly put this up because I wanted to prompt people if you're interested in this It would be great to share feedback on it to for you to play with it talk to us talk to the w3c's working group Because I think that we really want to get to a great place with this api Okay, so now you've got users who are logged in they can pay for things The final area that I really feel unlocks the potential for progressive web apps for the web as a platform Is connecting to hardware Now the web of course already has access to a lot of hardware devices accelerometers on my phone game controllers camera audio input audio output midi devices lots of other stuff Um, but I want to focus on one area that we've been working on lately Which is bluetooth Now when I say bluetooth, I'm not talking about headsets. I'm not talking about mice Those are bluetooth devices, but I'm talking about things like heart rate sensors And the latest made major version of bluetooth version 4 Which is actually like six years old by now, I guess Introduces this thing called bluetooth low energy now. I'm sure you've probably heard bluetooth low energy But you probably don't know why it's really exciting But the interesting thing is that it's also really weird Because unlike other tech like wi-fi or ethernet Which consistently increased their bandwidth version over version if you look at bluetooth on the right hand side here um version 4 seems to have fallen off a cliff like Why did they go from a transfer rate of 54 megabit to one of 0.3 megabit? Well, the answer is actually pretty straightforward. It's power and cost bluetooth one the bluetooth creators wanted to Evolve bluetooth into a technology that could be integrated into thousands of devices Like dozens of devices that you would use on a daily basis And when you do that you have to make sure that it's trivial to pay for you know Trivial cost upfront and it's trivial to maintain and it's trivial to fund the battery to like continue to keep it powered So when you look at this end to end It comes down to batteries and batteries are frequently something like this. It's a cr2 cr20 32 battery Like this is what actually powers the clicker that I usually use It doesn't provide a ton of power like this this won't power my laptop for very long at all And this explains why the transfer rates are so low because it needs to consume less power So if it runs at a slower rate and runs the the transfer at a slower rate It'll save a lot of power now You don't have to worry too much because most of the scenarios where you're going to use bluetooth You don't you're not trying to push like 4k video through this right like you're pushing control instructions for racing cars Or you're pushing data for a bluetooth le printer Or you're controlling bb8 because this is actually a bluetooth remote control robot Um, there are also devices like this. I actually have one of these Up here. This is a dotty led notification display Which um, you can have this display anything you want you can put custom patterns on it But you can also set it up so that it flashes red when something Bad is happening or whatever and I usually have this sitting on my desktop and doing doing weird stuff Now I want to take a look at how this works in practice. I'm going to start with a little demo here. Um, I have a bluetooth le device Here called a play bulb candle This is a mood setting led candle. So we're going to you know, bring the mood in here You can buy these for about 20 bucks Online you can actually buy them a lot cheaper if you buy them in bulk But the cool thing about this and you can tell already is that it changes color. It's a full color led And let's switch over to the uh, the remote here. Let's Pull out my phone Sorry, I have to leave the light off on on this because the color actually shows up then So i'm going to open up my demo page Connect to the device and it asks me what I want to pair with so I'll tell it the the candle And now from a web page with javascript. I can directly control this candle Kind of cool The candle actually it has a few other things in here too like I can set modes in it So it flickers a little like a real candle It flashes or pulses or does the rainbow effect Which personally I tend to think of as the seizure effect But let's turn that off now the really cool thing though we we actually just uh, just put this up a few days ago is um This has a sensor in it. There's a tiny little hole. You can't see it from there Can't even see it really in the the camera But it's a sensor for when you blow the candle out So i'm going to blow the candle out and watch the watch the screen instead Oddly you can blow it back on too, which is kind of strange But okay All right, let's go back to the slide deck Okay, so Before I dive into the code. I need to give a few basic terms from bluetooth There's two two roles in bluetooth or the central device my phone a peripheral device the candle and this weird thing called gatt And gatt is how these things communicate. It's a generic attribute profile The peripheral device has what's called a gatt server And that basically lets you ask it questions about what kind of services do you provide What characteristics do those services have and let you read and write those values So Yeah, that's pretty much what I said here. So Basically each service contains one or several characteristics can have multiple values Some of these are standardized like battery service to tell the battery level is a common thing You can query any device that supports the battery service How you know what level is your battery at and it will tell you In a consistent way Now I want to run through some javascript code super fast on how to do this We actually have a code lab on how to do this. We have a number of the devices here That you can play with tomorrow if you want But in general you just call navigator bluetooth request device You pass it some options that lets you filter what devices there are because there's tons of bluetooth devices around in most common scenarios today And actually this filter list is not optional you have to filter it down somewhat you have to say Well, I'm looking for something that's you know named play bulb or I'm looking for something that supports battery service or something like that So this that's what this example actually does is it looks for anything that supports battery service Once you've selected a device, you know once we've popped up that dialogue the user is chosen to pair it You have access to a bluetooth device object Which you can connect to the gat server and you can ask it um ask it what it supports Or you can ask it for a specific service Two things that I should note here one when you request the device to begin with it has to be inside a user interaction Like a click on a button And secondly of course like all Powerful features that in the web platform now you have to do this from secure htbs pages Works fine on localhost too, of course So then you can get services and characteristics So here you get the service the battery service you get the battery level read value tells you what the battery percentage is Pretty straightforward writing to services is actually just as easy This is the code to write the color to the play bulb candle So you start out you request the device you connect to it You connect to the candle service you connect to the candle color characteristic And then you write it like you write a value to it So this is pretty straightforward although you're probably asking wait a second They're these magic candle service uuid values and candle color uuid So it's possible your bluetooth device comes with the programmers guide Some of them do you can actually get one for the dotty But if not you can also install There whatever their control software is like there's a play bulb candle app for android And then enable the developer option in android settings that lets you snoop on the packets And you can tell what characteristics and everything they're they're using Now to be notified When a characteristic changes like when I blew out the candle All you have to do is add an event listener on when that characteristic changes Whenever the characteristics value changes the event handler gets called I did by the way want to briefly connect web bluetooth with another project The physical web so physical web is about beacons Low-cost bluetooth devices like this that just broadcast a url like bluetooth devices broadcast their presence anyways These broadcasts specifically a url so people in the first few rows you may actually be picking this one up Um, but then the goal of them is to make interacting with smart devices as simple and fast as possible So as long as physical web is enabled on your phone You will actually see physical web pages are nearby and they get filtered by a web service This won't be too spammy And the train that you're on can actually broadcast the link to their schedule A parking meter can broadcast The payment app A dog collar can broadcast its owner's contact information Now in the future though, this is the cool part. This is why i'm connecting these because this isn't a physical web talk In the future, we're going to integrate the physical web with web bluetooth with a feature called referring device So if you navigate to a physical web beacons url This actually gets exposed when we load the page that it came from a specific bluetooth device And when you know that this exposes the gatserver the bluetooth device directly So if you walk up to a parking meter You don't have to figure out then which actual parking meter am i at because it just went to a url You can actually make sure of that because you're connecting directly to the device So web bluetooth Requires you to flip on an experimental flag in chrome today It also works on chrome os chrome for android marshmallow chrome for linux We're diligently working on the os 10 and windows implementations If you're on lollipop you can still use it, but you have to use a chromium build and it's also implemented in opera So to get started if you're interested by the way just google web bluetooth samples. It's really the easiest thing Like I said, we've got a codelab that we're running tomorrow And a bunch of devices to play around with we also have a pile of physical web beacons That you can keep we don't have enough for everyone I don't think so we'll figure out how to uh, you know throw them at people was my idea, but They said no With that, um, you know, I I hope this gives you an idea of some of the exciting areas That are going to make progressive web apps even more exciting in the future I hope you've learned a lot today Um, please come back tomorrow. We've got lots more talks from other browser vendors Partners and you have a chance to talk with us in office hours And experiment in the codelabs So thank you very much, and I think paul kinlan is going to come back up and close things out