these graphs is this green line. It's kind of an outlier down at the bottom. Again, we don't know why this is for sure, but one hypothesis we have is that on Android, this sort of serious web browsing on Gmail, Facebook, things like that, that stuff that Android users are doing in apps. So from Chrome's perspective, they see more of the non-HTPS traffic and less of the traffic that tends to be HTTPS that Android users tend to do in apps. So again, that's just a hypothesis, but we think it kind of makes sense and it means that as the mobile web becomes more and more engaging, as you all build and gain traction on your progressive web apps, we would hope to see this line kind of continuing to go up and hopefully catch up with desktop. This is great news. Developers like you are adopting HTTPS. You might be wondering why. What is driving this slow but steady increase in HTTPS usage? And we can't tell you for sure, but I want to pull out a few things that we hear over and over again anecdotally from developers who are transitioning their sites to HTTPS. First, modern browsers like Chrome and Firefox and others are restricting usage of powerful features over insecure HTTP. Some features have already been deprecated and are already not available over insecure HTTP, and some will be restricted in the near future. So these are things like geolocation, service workers, push notifications, the payments and credential management APIs, all sorts of things that you've heard about today that you need to build a progressive web app are increasingly only available over HTTPS. So we're not doing this to be mean. We think it makes sense, and that is the best thing to give our users more control over their privacy and devices and data. And I think this is easiest understood with an example like geolocation. Because if a website wants access to my location and if I grant them access to my location, then I'm giving them information about potentially where I live, where I work, where I shop, where I go to the doctor, what I do on my weekends, all sorts of things that is pretty privacy-sensitive information for a website to have. And that may be fine. I may be perfectly happy sharing my location with some website, but I can't really make that a meaningful decision unless I know which website I'm talking to. And that's exactly the guarantee that HTTPS gives you, which is why we are increasingly restricting access to these privacy-sensitive, powerful features, unless the user actually knows which site they're talking to. As I said, Chrome is not the only browser doing this, and just one other example is Firefox. In this blog post, they actually announced that they're eventually planning to require HTTPS for all new features. So this is something that browsers are pretty much united around the hope that it makes sense that if you're going to grant access to privacy-sensitive information or a powerful feature, the user should know which website they're granting that access to. We think this is one of the drivers behind HTTPS adoption because we hear it from developers. One example of this is the BBC, which cited these restrictions on powerful features as one of the reasons that they decided to move bbc.co.uk to HTTPS earlier this year. Another consideration that we think is behind the slow but steady increase in HTTPS usage is that HTTPS performance is getting better and better every day, and it's no longer kind of the bottleneck that it maybe once was 10 or 15 years ago. What you're seeing here is a website built by one of my colleagues, Ilya Grigorik. It's called isTLSfastyet.com. TLS being the protocol underlying HTTPS. So the answer is yes, but that's not just what this website tells you. It tells you about all of the performance improvements and enhancements that are coming out every day with HTTPS, and it tells you how to configure your server with them and which servers support them. So it's a great source of information about HTTPS performance. I want to draw particular attention to HTTP2, which is the next version of HTTP, and offers a whole suite of web performance improvements, but it is critical in this talk because HTTP2 is only available if you're also using HTTPS. So what we hear from developers is that in the case that they do encounter some performance hit when they move to HTTPS, it can often be offset, more than offset, by the performance advantages that they unlock using things that are only available over HTTPS like HTTP2. These are some of the things, these restrictions on powerful features, the improvements in HTTPS performance, these are some of the examples of what we think is driving this slow but steady increase in HTTPS adoption. But while things are moving in the right direction, we still have a gap to close, and we need your help doing that. We need your help by adopting HTTPS on your site so that we can get as close as possible to HTTPS everywhere. And we need that, we need to be as close as possible to HTTPS everywhere if we're going to get to the place we want to be where we're honest with our users about connection security. My point here is that if we were to tomorrow turn on this warning state that we want to have where we do this kind of scary red dangerous warning indicator on insecure HTTP, if we were to just turn that on tomorrow, it would probably be a little bit counterproductive. Users would see it everywhere, they'd see it all the time, they'd learn to ignore it, they'd have to ignore it to kind of use the web, and they'd kind of get trained to basically just not see it. So that's not what we want. We want it to be the case that insecure HTTP is a pretty rare occurrence. So rare that when the user encounters it, we can show them this warning and they will pay attention, they won't be scared or confused or habituated, they will see it, they'll pay attention and they'll understand the risks of the situation that they're in where they don't have any guarantees against attackers reading their content or injecting malicious content or any of those risks that I talked about at the beginning of the talk. So that's what we're asking of you. We're asking you to adopt HTTPS on your site. It helps you and your users and your site and it also helps us in our mission to make the whole web more secure, to make users more educated, and to make their activity on the web less of a risk for them. But we know this is not always easy for developers. It can be overwhelming, and that's why we at Chrome and at Google and in other organizations are mobilizing a lot of support and investment around helping you transition your site to HTTPS. One of the organizations that is becoming critical in this movement is called Let's Encrypt. Let's Encrypt is a certificate authority. A certificate being a cryptographic proof of identity that you need in order to use HTTPS. It's the thing, the cryptographic proof that proves that your site is who you say it is. If you say your example.com, you get a certificate proving that your example.com, and that's what gives your users the guarantee that their browsers are actually talking to the real example.com. Historically, getting certificates has not always been easy, and it's not always been free. But thanks to the work of organizations like Let's Encrypt, it's now possible for you to get a certificate very quickly with no money, and they also provide easy command-line tools for automating the management and renewal of your certificates. So we think this is a critical part of internet infrastructure going forwards. Chrome has made a large donation to Let's Encrypt, and users are funding it as well, because it's becoming such a core reliable part, a core part of their, the process of running a web application that they've come to depend on. And in case you don't believe me that Let's Encrypt is here to stay, I think you can see it just in the numbers. This is a critical part of internet infrastructure that is really going to change the way that people do HTTPS. It already has. It's internally a little bit more at Chrome and at Google. One of the ways that HTTPS sometimes worries developers is ad revenue. And if you haven't heard about this concern before, it might seem a little bit random. What do ads have to do with HTTPS? The connection is that when you move your site to HTTPS, you have to move all of your content, all of your third-party resources, including ads, in order for your site to work properly. So developers are often worried about having to move their site to HTTPS, needing to move all their ads to HTTPS and therefore losing ad revenue from ads that are only available over HTTPS. To help alleviate this concern, all Google-sourced ads are already served over HTTPS. So when you move your site to HTTPS, you will not have a revenue hit from Google-sourced ads because they are already available over HTTPS. And this is backed up by developers in the wild, the Washington Post moved to HTTPS recently and saw no hidden revenue from their Google-sourced ads. Another Google service that people sometimes worry about when moving to HTTPS is losing search ranking. Because anytime you make a large change to your site like this, you should make sure you follow the proper steps to make sure you minimize the disruption to your organic search traffic. These are some of the questions that people have. How to move their site? Do they do it all at once? Do they do it a little bit at a time? What kind of fluctuation should they expect? And more technical aspects of the move, like what do they do with robots.txt and their site maps and how do they tell Google that they're moving to HTTPS and all those sorts of things. What we're doing in this space is expanding and improving upon documentation. And we really like to hear from developers about what their questions are so that we can answer them publicly. These two FAQs, I recommend to people all the time. There are just lists of questions that people have with very straightforward practical advice answering some of the questions I had on the previous slides. And we also have a web fundamentals guide that walks you through the process of setting up and configuring HTTPS performance tuning, things like that, and also has a section on how to handle your transition from the perspective of Google search ranking. ENAT was able to move to HTTPS with, as you can see, minimal disruption to their search ranking. So we are hopeful that we've improved the documentation to such an extent that if you just do a little bit of research and follow the steps and the documentation that we provide, this isn't a traumatic thing for your search ranking. It really shouldn't be nearest and dearest to my heart. And I could spend a whole talk talking about web platform and browser tools that we're building and sometimes standardizing and evangelizing in other browsers to help developers like you move to HTTPS. These are things that I work on pretty much every day, and I just want to give one example, which is the DevTools security panel. So if you move your site to HTTPS and you open it up in DevTools and you go to the security panel here, you'll see that it's designed to basically help you figure out if you've done it right. If you have any problems, if you've made any mistakes in your transition to HTTPS, figure out what they are and tell you how to fix them. These tools are ways that we at Chrome and at Google want to guide developers into using HTTPS on their sites. But simultaneously, we're planning to start easing users into the idea that HTTP is bad, because we want to get to eventually a place where enough developers are using HTTPS that we can really warn users when they have a lack of connection security on insecure HTTP. And we don't want to just jolt them into that world right away. We want to kind of ease them into this association between HTTP and bad. This is the new UI treatment that we'll be using for some insecure HTTP sites in Chrome 56, which goes to stable in January. So you can see we're still doing kind of the neutral informational icon, but we're adding the not-secure text to start to educate users about what it means to be using insecure HTTP. And we'll be specifically launching this for HTTP pages that have passwords or credit card inputs on them. So our goal here is to use passwords and credit cards as a signal that the user might be in a particularly sensitive situation in which they want to be particularly careful with their data and in which it's especially important to warn them about the risks of insecure HTTP. So this feature is still in development, so I want to stress that it's subject to change, but you can go try it out in Chrome Canary today. And we would love for you to do that, both to report bugs, to see what it's like browsing the web with this feature on. I find it really interesting to see what it's like a glimpse of browsing the web in the future. And also to try it out on your site and see if your site will have this UI applied to it, if you're not using HTTPS yet. So to do this, you just go download and install Chrome Canary if you haven't already. Go to chrome colon slash slash flags and find this mark non-secure as flag and flip it to the option that says something about passwords and credit cards on an HTTP page. So if you do this and then you go browse around the web or browse around your site, you may see that we're doing, as I said, we're detecting when a password or a credit card field appears on the page and using that to trigger this not secure warning from your users. So we really encourage you to try this out. Try out your own site if you're not using HTTPS. And if you find that your users will see this not secure warning come January, maybe you want to start using HTTPS by then. Our hope is that this does help incentivize developers like you to move to HTTPS and also starts to sort of build the association in users' minds between entering sensitive data and the lack of security of HTTP. Fortunately, it's not just about negative indicators. We have sticks and we also have carrots. If you download Chrome 55 beta, we're already using this secure chip for sites that are using HTTPS. So it's not just that you'll get a not secure warning if you have a password or credit card on HTTP. If you adopt HTTPS, you get this shiny green badge next to your site and the user is that, hey, you are using a secure connection. So we hope that this provides some incentive to adopt HTTPS in addition to all the other benefits that you get, like the privacy and security benefits for your users and the ability to use powerful features like geolocation and service workers that you get with HTTPS. So that's the glimpse of the very near future. These secure warnings for secure sites and starting to show not secure warnings, which is closer to the honest truth about HTTP for some sites in Chrome 56. But this is where we're going. We hope to get here as soon as possible to a place where the web is as close as possible to HTTPS everywhere, so that we can be fully honest and truthful with our users about what insecure HTTP means. One of the things that we're considering doing in the future is sort of gradually picking more and more signals. So in Chrome 56, it'll be passwords and credit card fields. Maybe in the future, it might be something like when the user is in incognito mode or when the user is downloading a file over HTTP, things like that, more and more signals to kind of gradually make an assumption that the user is in a potentially sensitive situation and warn them more and more aggressively about the insecurity of HTTP until we get to the world that we want to be in. The theme of my talk today has been honesty. The new transparency report metrics show an honest picture of the world when it comes to HTTPS usage. It shows that we're moving in the right direction. We have a slow but steady increase, but we need your help closing the gap by adopting HTTPS on your site, which we think is good for you, for your revenue, your brand, your user experience. It's good for your user's privacy and security, and it's also good for the web as a whole, the whole ecosystem, by helping us get to a point where we can be fully honest and truthful with the people using Chrome about their connection security. Thank you, and enjoy the rest of the summit. I'm not sure. I'm not sure. I am. I am. I got the sound. You don't. Oh, that's good. That's after a good start. Hey. Hey. Can you hear me now? No. Yes. Good. Hello. So this isn't Jake. Technically, it is actually time for a break, but what we thought we would do if you want to get a drink or do whatever, we're going to do some live coding, which never goes wrong, obviously. Challenging the demo guards is always a good idea. And you see how my day's gone in terms of bugs. So, Serm is going to be doing the coding. And what we're going to be doing is we're going to be adding a service worker to a site. And the reason we wanted to do it was to give everybody an insight into just how to think about the problems of putting a service worker onto a site. So this is in the theme of a YouTube show that we do about once a month, which is called SuperCharge. Yes. And we have been building things before, where we have built a router, where content is being XHedArt in and you get a nice animation when you do navigation to a different site. And we're going to use that and make it offline capable. And that, stay. Stick around. We're just getting set up over here on the AV, as you noted. So, how... Oh, they're still going. So, the kind of things you should be expecting from us today are things like async await. We're going to have a take a look at... Oh, yeah, we're going to use... We're on. Oh, we are on. Perfect. Here we go. Let's roll. Now, if you've got any questions during this, you can go to the Chromium Dev Slack and you can ask them in the main chat area there. I'm going to be watching that and I'm going to interrupt him. So, he can basically forward your questions to me and probably make me more do mistakes. Yeah. All right. So, let's get started. So, what you see here is the thing that we have built a while ago.  And as you can see, we are only requesting a partial, which is just a single line of HTML that is being swapped in and all the rest is JavaScript and transition magic. And this is what we want to try to make work offline. Oh, somebody went full screen. That is not good. Let's not go full screen. So, the first thing that I'm going to do is I'm going to register a service worker and because I'm a fast typer, I'm done. You cheat.  So, what I usually start with is a string for a version. Wait, wait, wait, wait.  So, you've got a... Right. If service worker and navigator, let's talk about that just a... That is progressive enhancement. Right. So, basically it checks if the navigator object has the service worker call and if not, we're not going to do anything. If it does, we can actually register a service worker. So, we don't register the service worker. We tell the scope, you're going to control everything from forward slash. You're going to control every request. Everything. Yes. Right. As you were. So, version string I usually do because it is a nice place to force a reload of the service worker. So, the service worker file is going to be checked if it has changed, if it is byte equivalent. Correct. It is not going to be reloaded. If it's something changed, a whole new service worker is going to be spun up. So, a version string is a very nice place to force this kind of behavior. Now, good news. If you set far future caching on your JavaScript files, at most the spec says you're going to wait 24 hours before Chrome, or in fact any browser that supports service workers will go and try and get a new version of your service worker. But you could be stuck with the service worker version for 24 hours. So, typically on a service worker, you want to make sure that you're serving it. For example, today, we changed the schedule of Chrome Dev Summit. If we had been stuck for 24 hours on the same service worker, that would be awkward. Bad. Right? So, there we go. So, the first thing we're going to do on install basically always looks the same for me. I usually do a skip waiting in here, which means sell.skip waiting. Type O. He caught me. So, we're not going to wait for SoC shutdown. We're going to take over immediately, which is also what we have to do in activate. Okay. So, let's talk very quickly about the life cycle. So, when a service worker is downloaded, it goes through an installation step. I think Sheik wrote a really good article about that. Yeah. I mean, there's a brand new article on developers.google.com slash web slash fundamentals, I think it probably is. It's probably on fundamentals. And I'll find it and I'll post it into the Slack in a moment. But basically, it talks through the life cycle. But in the short version, you have an installation step. When a service worker is finished installing, it will activate as soon as any, as soon as it's able to, which largely involves any connected clients they're called have disconnected and it becomes available. Otherwise, you have to wait until they've all disconnected. You've got on install. I'm not going to skip waiting. On activate, I'm going to claim all my clients. So my new service worker is active now, but it hasn't taken care of all the open tabs if you have multiple ones. Self clients claim says, give me all the tabs that they are and I'm going to take care of them from now on. Okay. So if you've got an existing service worker, you're just basically kicking the old one out immediately and saying, I'm the new one. I will handle everything from this point on. Exactly. Okay. And for the on fetch for now, I'm just going to say, I'm just going to do a a not service worker basically not going to do any offline logic, just any request the page does. I'm going to do the actual network and pass it back. So if we reload this site now, we see the service worker just got installed, which is good. And now on reload, we should see every request twice because the website does a request for example, the SC view file, which gets to the service worker and the service worker does the actual fetch, which is why it also shows up down here. So everything is still working the same, but we have a service worker now in between our website. So it's really worth pointing out this, that little cog there is the thing you're looking for and also if you have a from service worker, that is good things to watch out for. But you are seeing that two steps. Something went to the service worker, the service worker did a fetch and then it comes back. So a pretty common way is to download the files that you know the user is going to need on install. And that's exactly what we're going to do. So we're going to define an assets array and these are the files that we need. Dude. Boom.  And I was like, how long has this taken you? And he's like, I've practiced and I can do it in like 11 minutes. I didn't realize it was all snippets. These are actually the two snippets I have. You're done with snippets now because it's boring tidying this out, I thought. There's no semi-colon at the end of that assets declaration. Well, it's not technically wrong. It's just... Awkward. If the linting was switched on it would have a problem. Now we're going to do interesting. We're going to write async function. Oh, yeah. Which now everybody knows will run synchronously. Exactly. From the quiz. Until I do await and do cache's open static. Right. Now you've got to explain what's going on here. Exactly. So async function just think about it as a function. It is actually a function we're trying to promise. Just that we're on the same page. We're blocking it by saying it's an async function. Because only inside async functions we can use await. And we want to do that because it's cool. And that means that this function actually returns a promise. So everything in here will basically be kind of rewritten into a promise chain but it's so much more readable now. Okay. So we're saying we've got an async function. We're saying open the caches and... So usually you do like a dot then afterwards and you get the cache and then you can do something like you can actually just await it for it. And this is the same as a dot then but puts it into a variable which is... So it reads like synchronous code. Like I want the cache and then I want to do something else and something else but under the hood it's magically doing sort of promisey type stuff. So the next thing is another await where we can do cache add all assets. So this step is going to wait until we have downloaded all the assets in our array put it into the cache and then we will return skip waiting ultimate value of this promise that the async function returns is going to be self skip waiting which is what we want to pass into wait until because we're done without setup but before that all the other steps are going to happen and we can check this works by reloading the page because now the service worker... Oh! Remind me I'm going to write a lot of async functions if I forget these two parentheses at the end shout because it's a painful to invoke this function right away. Ew! So let's do this again. Sorry that was involuntary. So service worker and we see now it downloaded all the files again. Which reminds me when we do these it's not production code. I'm not saying you're writing by code. Awkward. There is a sense in which we do this stuff to kind of show the approach that you take this isn't necessarily stuff we'd say just take this copy paste and you're good to go. Yeah. That is important. It's worth mentioning. So now that we have things in our cache we know that everything from our static folder is going to be in our cache 100% because we are downloading it on install. Okay. And this is what I want to take advantage of in our on fetch. Well can you can you go back and reload the page and then show them the cache inspection in DevTools. Really useful. So at this point we should have all these assets in the cache, right? So we have the cache storage and we can go and have our static cache and all the files are in here. This is really useful to see if everything actually landed. Can you show the response? No you can't. Okay. I still don't know why. I don't know what this this thing is. They should say okay but it just doesn't like you right now. I am in canary because async functions are only in canary so there might very well be bugs right now. Okay. But you normally see you normally see the fact that it was an okay request kind of came through. So if I have something in static I don't even want to bother with going to the actual network because I know I have it ready. So something that I kept finding what sort of doing is actually parsing the URL. So event.request.url is the request URL but it's just a string. I actually want to have it separate into like the query part, the path, the domain and all these kind of things. So I am just going to attach a new thing to this URL object because what I can do now is event parsed URL path name starts They don't add that to the spec you are going to feel really awkward. A little bit, right? So basically what I am checking is if the past name starts with static I will give it some special handling namely I am going to respond with a cache.match event request. So I am looking at the cache for the request object and going to respond with it and I know it's going to start and when we get a fetch from the page that says I want whatever URL hopefully we are going to find it if the URL starts with static we go find it from the cache we are pretty confident and we should be able to return it. Otherwise we are going to stay with fetching for now. So what should happen in our network tab is that all these server cycle requests should disappear. So I am going to reload once which is going to trigger a version one as well. That bottom request there is the service worker trying to do an update for a new version trying to find see if there's been an update. Checking if it's byte equivalent or not. So you will see that kind of going the service worker looks for the new service worker so that's normal. So for the rest right now if there's a request for something that we don't have in the cache for example our index HTML it goes to the network and just gives it back to the browser and then it says how many is it? Five. Five assets. If I request something that's not in there we go and fetch it but then we just kind of it's if we're offline we wouldn't have it for next time. Exactly. And that's what we're going to change. And I like to write functions for the different caching strategies. So in this case I'm going to do a stale while revalidate. Revalidate. There we go. So what this means is stale while revalidate means if we have and in the background fetch it from the server and update the cache. So we see this typically on social networking sites where they kind of go here's all the posts that I've got stored. Enjoy those. Meanwhile I'm also going to go off and get the latest set of posts and when I've got those I'll update my collection for you. So one nice thing about the strategy is that we're definitely going to do both. We're going to do fetch and we're going to do check the cache so we're going to somebody's asking on the chat and if you're not in the chat and want to join in is the chromiumdev.slack.com and it's we are in the general channel and somebody's asking if the code is going to go on to github totally the answer is yes we have I will post the link in the chat if somebody else doesn't get there before me we have a UI elements samples repo which has the whole all the elements that we've built all the stuff we've built so far for you to look through and this will be no different so it will be in there I might clean up a little bit afterwards some comments just to remind you what I was actually doing because I'm not going to write comments now like who does really come on so we have two things that we can do now first we have to figure out what to respond with and this is something that I want to give to you in respond with try to get to the response as fast as possible and nothing else caching you can worry about and wait until so we have event respond with and event wait until so respond with expects a promise that resolved the thing that is going to be given to the browser as the response to the request so for example you could respond with the fetch and a fetch is going to return a promise which will ultimately result in the content of the thing that was being fetched which is a response response object wait until however keeps the service worker alive if you want to do some further work twice the service worker might get killed before you actually save it yes now this is an interesting part of service worker work is that they there's no promise given or no I shouldn't say promise there's no guarantees given that a service worker won't be spun down okay so once say for example you've loaded the page even if the tab is open it can be spun down if so once someone has reloaded the page the browser is well within its rights to say I no longer need this service worker but the dev tools says now that service worker termination by a time out time I was canceled because dev tools is attached so it was going to shut down the service worker but because dev tools is attached it said I'm not going to do that in case you want to inspect what's happened in case you just want to have a look at the service worker because when you log an object from the service worker you can't expand it anymore if the service worker has been killed because the context is gone so it's just a thing to do which in this case I assume is going to be putting things into a cache well in respond with no in respond with you're just going to worry about what the response is so our response in this case is going to be a promise dot race because whatever we have the fetched version or the cached version I just want to return whatever is there faster so promise dot race is a function that takes an array of promises and gives back whatever promises settles first okay so okay so you've got a fetch you've got a look in the cache you're going to say don't care pick one whichever is faster most of the time I would expect that to be the cached version yes however if we are offline fetch rejects and promise dot race doesn't care if it's a reject or a fulfill it will turn whatever settles first which includes both so when we're offline fetch is almost immediately going to throw and be like I'm offline and can't do anything so the cached version is going to say okay here is your rejected promise have fun which is not really what we want so what I do in this case is I'm just going to put a little sneaky catch to the fetched version and say if you're going to reject just turn into the cached version too nice that is well cheeky sorry I'm totally stealing that so what's going to happen now is I now we have to think about this can be a response but it can also be undefined which is what caches dot match returns if it doesn't have anything in the cache so in this case what I'm going to do is if the response is not valid so it is undefined I'm going to return the fetched version so this covers all the possible outcomes because you also have to think about there is a way if we are actually online the cache could and then we want to wait for the network so at first glance what appeared to be quite neat and tidy you're kind of going right fetched and cached but if the fetched version decides it's offline and we'll switch to the cached version but if the cached version doesn't work out for whatever reason we'll go to the fetched version yeah and now it gets everybody following along there's going to be a pop quiz actually doing a pop quiz we might actually have a quiz question damn nobody's going to because when we're offline it's going to reject so there might be a way that cache response first with I got nothing see Matt go on who's one of our colleagues he just says I was just sick in my mouth go on T I'm going to get back to him now so what I'm going to do now is fetch could reject so if that happens if we're down here and fetch reject we know nothing's in the cache and we're offline there's going to be a new response offline with nothing to say 4-4 done oh that's such a grown way of doing it I know I just be like I am German okay I would have been like yeah I don't so let's comment this out for a second reload the page get the new server server any errors looking good looking good 4-4 on the local host what did I do wrong no now at this point I would try well what was I doing I find n I was doing I just body heard of the rubber duck theory yeah few hands going up if you've not heard of it the idea is that you have a rubber duck on your desk and when you hit a bug you introduce yourself to the rubber duck hi I'm Paul here's my problem and as you explain your problem to the rubber duck in this case Duck is enough to help. How's it going? 31. Cashed with a D. It's a bug. It's a typo bug. See, I think if you'd had linting on you, you'd have got that. Me, me, me, me, me, me. Yay! A plus. So, everything should totally still be working. We're still fetching everything. We're not putting it in the cache yet, so let's fix that. We have this thing done, which basically does the right thing. Just believe me. I do. I'm just... OK. And now we're going to talk about the caching. This one is actually simple. So, what we're going to do is we're going to wait for... Is it semi-simple? No, it's actually... I'm looking at the other one. So, we're going to wait for the fetched version. We're going to wait for our fetch. We're going to open our cache.caches.open. I'm going to call this one dynamic because we're... We had the static stuff. This is the stuff that we're kind of going... Oh, we didn't have this to begin with. So, maybe, for example, this would be where you'd store your posts. The stuff that changes over time, right? Maybe use a generated content. Incidentally, if you're taking this approach, make sure that you have some kind of purging strategy. Otherwise, your caches can grow forever more. Hashtag topical. There you go. So, you want to make sure that you have a way of getting rid of old stale data. So, we wait for the response, we wait for our cache, and then we put the response in the cache. Done, almost. So, as I said before, the fetch can reject if you're offline. So, we are just going to catch that error and just... Not do anything about it. And also... Wait, did I miss anything?    So, this should be working, right? Or not? Oh, no. We have actually something subtle, which is why I almost forgot about it. So, let's imagine this. The cache got nothing. That means that our response with returns our fetched version. And then we get into a wait until and we want to store our fetched version. So, we're using fetched version twice. Ooh, ooh. I know this one. That doesn't work because the body of a fetch is a stream and you can only consume it once. So, what we're going to have to do is we're going to have to do a fetched copy. So, this is the same as the fetched version, but the response should be cloned. And then down here, we can wait for the copy instead of the fetched version. Okay. So, let's reload and see if this works. Reload, new server tracker and another reload. So, we can still go to about. We can still go to contact. All good. And now, let's go to the applications panel and go offline. Reload still works. About, cool, contact, cool. Misk is not going to work because we haven't visited Misk just yet. So, this is just going to put up our great spinner. Okay. So, what we would want to find a way to kind of handle that one nicely and be like, sorry, can't get this offline. Maybe. Not today, though. No. I mean, it's almost like you're saying with time constraint that I keep interrupting you. It's almost like it's revenge for me for all our other shares. What doesn't work, though, is that we cannot refresh here. It just doesn't work. No. Because... You've all got errors as well. Well, yeah, because I just... An unknown error. It's great. Oh, okay. So, in the dynamic, we have the root page, but we only have the partials for about and contact. So, that's why we can only refresh while offline on home but not about and contact, because we don't have the complete page cache just yet. Yeah. So, a bit of background for you. When we made this originally, each individual page, we served the whole thing. And then, on the updated version, we only pulled in the bits that we actually needed for the XHR so that when you go from home to about, we only pull in the little bit that was needed. And so, what we're saying is that the thing that's caching, it's only caching the changed bit, rather than if you refresh, it goes, well, I haven't got the full about page or the full misc page. So, we need to figure that one out. So, what we're going to do is, and this is where it actually gets exciting, we're actually going to do the templating and the source work right now. So, we're going to pull in our header partial, our footer partial, and do the assembly of these partials in the service worker. The same thing we built on the server side in the server side rendering episode, we're going to put that into the service worker. So, the first thing that we need is our partials. So, I'm just going to sneakily put those in our static cache, which is header.partial.html and also footer. Just so you see what these look like, they're just partials, the start document with a little bit of, this is the wrong document, but it's similar. Let me check where it is. There it is. It's just basically the top of the document and the bottom and we put our own content in between and there's a little bit of templating magic, which we're also going to take care of. So, now we have the partials in our static cache and now we need to figure out when is this request for a web page, for one of our top level pages instead of any assets or other links we might add later. That seems like something that doesn't have partial on it and would have gone to the dynamic cache. We solved this when we built the backend and we have this great regex that does this. Hang on, are you sure you don't want to just reuse the code in the kind of isomorphic way? This is almost what we are doing. Almost? Almost. And I'm not going full isomorphic because I think isomorphic has the flaw that it assumes you have note in the backend, which sometimes, or maybe most of the times, is not the case. So, we're going to, when you want to do templating in the backend, choose a templating language that has multiple language bindings. So, whatever you use in the backend, all right. So, on the fetch, we're going to see if our top level section regex matches our event parse URL path name. And if that's the case, we can call our function that we are about to write, which is going to build the site. If not, we're going to use the existing code that we just wrote. So, we are going to write build site, which is going to be interesting. So, event respond with, what is going to happen in here? Obviously, we're going to use an async function because they're nice. And I'm going to do these because I'm going to forget them. So, the first thing that we need is we're going to need to get a hold of our files. So, the files that we need are caches.match, header.partial. So, again, those from the static cache. Because we know they're there. The footer. And in here, we are going to basically use our stale-wire-revalidate function more or less with the event, parsed URL to string, plus partial. Got you. So, you basically, okay. You need a comma after that one. I do. So, actually, that's, and because both caches.match and everything else is going to be a promise, we are going to wrap this in promise.all. So, this is good, but if you paid attention, you know that stale-wire-revalidate doesn't actually return a promise or return anything. So, what we're going to do now is basically we are going to use this function and write a little wrapper around it that actually returns a promise.  No kidding. So, stale-wire-revalidate. It's so hard. Request. So, this is the request URL, and this is going to return, for all we know, a... A promos. A promos. I shouldn't mock you. I make so many typos when I'm typing. It's embarrassing. And there I am being unkind to you. And I never mock you for it. And yet you... I'm just unkind, aren't I? Yeah. I feel pretty bad about that. Pretty much. So, we're going to call our old function, which takes an event. We're just going to build our own event now. We're just going to pretend to be an event object, even though we are not. Because the only things of event that we're using inside the stale-wire-revalidate function are a respond with wait until and request. Wow. So, our request is going to be a request. Because, interestingly, both fetch and cache take both request objects, but also strings. Huh. So, this will just work. Great. Our respond with is going to be our result function. So, that means whatever this thing... You can see where I'm pointing it on my screen. Yeah, I was going to say... I'm a genius. Yeah. Well, this thing... So, whatever this thing is going to be passed into respond with, which now is the result function of our new promise, which up here will give back the value. And also, we need the actual wait until. So, we can't really create that. So, we have to pass it in. So, wait until. So, we have to put event, wait until dot bind event. Ew. However, it's going to get better. Because... I'm never writing a service worker again. Service workers are hard. So, the thing is... Your service workers are hard. Mine don't look anything like this. Mine are really like... And they don't work. That is true. They... So, the thing is something that just got fixed. I'm so sorry. I'm going, I'm going. I'm done. The thing that just got changed in the spec, but it's not in the browser, is that right now, you can't call wait until inside respond with or the other way around. Okay. You can only do it at the top level in the same tick that the event got dispatched. So, we are going to have to do our own wait until. And what I found out is a kind of dirty hack which I'm just going to use until this change lands. I'm going to put a new promise into wait until and just save the result function on a variable and just use that instead. So, that means that the service worker will now stay alive until the my wait until will be called and all the browsers should be happy even though we are technically calling a wait until function, even though it's our own inside respond with. The last thing I want to fix here is that we are appending partial to the string, but that isn't technically always correct because this might already be a partial request. So, that it would be question mark partial, question mark partial, which we don't want. The good thing is that we already have a parsed URL, a URL object which has search params. Oh, not catalog. Search params. And we are just going to set partial. So, that means if it's already set, nothing happens. If it's not set, it will add the question mark partial to our URL and we will always get the partial thing. Okay, so it's okay. We got our files. We do. The last thing we are going to need is actually get the contents out of our responses. So, our contents are the files, and of all of those, we are going to get the text. Okay, so you are making this request, the header, the footer, the actual bit in the middle, and now you are mapping that by saying, okay, will each one of those get the text for each of those? Exactly. However, text is a response. So, once again, we have to put this in a promise.all. Because, again, fetch resolves when you get the headers and the metadata, but then the body is a stream. So, dot text basically returns a promise and reads the entire stream, puts it in a string, and gives it back to you. So, now we have the contents. Our content, the thing that we are actually going to pass back is the contents joined because it's just three strings and we are going to concatenate them. And then we are going to return a new response with our content. So, this is basically how we do the templating inside our service worker. So, let's reload this. We are going to get the new service worker in, or not, but I missed something. That shouldn't stop it from working, though. Thanks, though. Offline, you checked the offline box. No, I did uncheck it here. Oh, that's an interesting bug. Usually those are synchronized, but apparently they're not. Thank you. So, let's... I got that. But it's still not working, is it? Okay, I'm just going to unregister my service worker because something is clearly iffy here. Stop. It does happen sometimes when you use Canary. Oh, there's like three service workers installed now. We should be on the safe side. Ah. Ah. Interesting. So, as you can see... That's exactly what it is. So, the default MIME type of response is text plain, which is really not what we want. So, in our response, we have to add headers, content type, text HTML. Reload. New service worker. Reload. Hooray. But, nothing works. Which is expected because I didn't do the templating. Oh. So, I still have my template expressions in here, so now we're actually going to load the templating library. Oh, if we use handlebars, right? I don't anymore because handlebars turns out to be like 80 kilobytes, and I found a nice little... a little library called DOT, and... Well, it is DO capital T, so I don't know how to pronounce it. DOT. All right. And this is one of the bits where I say this is our production code, because in this version... The line keeps coming up in the chat, by the way. People really clarify what we mean by it's not production code. So, I basically exposed the entire node modules folder. Yeah, why don't you? Why not? You don't do that in production. Please don't. But, in this case, it's just the easiest way and you don't have to actually think about the build steps in the background, how I'm actually bundling this or whatever. And also, I'm not doing any cache cleanup. So, if you actually bump the version, you're probably going to run into problems because old files might still lie around. So, there's definitely things that I'm just skipping over for sake of brevity, and because this is already complicated enough. Okay, so this is what I was saying earlier about the purging of caches. You want to make sure that... Cache invalidation is hard. Yeah, but it is definitely worth doing. Is it because we said service worker enough times? Yes. If you say service worker three times in the mirror, it's been really difficult at some conferences because I've just been whisked to the other side of the planet. I've just come to let you know that we've got a conference to do and there are other people who would like to talk. Fine. How close are we to the end? How close are we to the end? Actually, let me think. Where was I at? Oh, the templating. Yeah, it's literally two lines. Here we go. How long has it been literally two more lines? Well, it would have been done faster if you didn't... So we're going to take a template function. Our template takes event.request. We're going to reload. Oh, that looks okay. And now it should go back to normal. We're done. And now the test is to go offline. Really? We go offline. It still works. We can reload on all the sub pages because we're offline. It still doesn't work because we never went to the page. That's fine. And I'm done. Great. That code that code will get a lot of comments and will be pushed to GitHub and we will post the link in the Chromium desktop. And if you have questions, at theSerma on Twitter, at erotrist, and you can mostly bug me because he didn't write it and he doesn't understand it. That's true. They're laughing, but they know it's true. All right. Thank you very much. Have a good one. What are we doing now, Jake? Well, Sam's going to give it another go. Oh. We've got a... Is it the same laptop or is it... It's not my laptop. Different poll. Irish poll. No, he's not Irish poll. Let's be clear on this. So you'll notice that Sam's here. We would normally introduce the speaker and then sort of walk away, but we felt this time we would stand and stare. Hang around until something actually goes on the screen and then we'll introduce Sam. Hang on. You logged on that laptop. You know Paul Irish's password. You two are good buddies. I wouldn't share my password with anyone. Are we feeling good? Are we feeling confident?  Yeah. Right? Well, this time things are on the screen in front of me. That's a good sign. That's a pretty good start. I'm ready. You're going to be okay. Come on. Welcome on the stage. He's been here for a while. This is his second time, but first talk. Sam's encoding everyone. Hello everyone. Today I want to talk to you about what it takes to build a super fast mobile web experience. And to do that well, it's going to require us to plan for our performance. Here's my pitch to you. You've all been in that meeting room. When your manager or boss has asked you, well, does this site work on mobile? And you think, well, sure. It's worked on a small screen size on my desktop. And I wrote some CSS, so things scale. So definitely this works on mobile. But that mentality has a flaw. And the flaw is the mobile web is no longer just this subset of the web that you think about at the end of your development. The mobile web is just simply the web. And we see this through the numbers. Mobile traffic is actually outpaced desktop traffic since 2014, and it's only continued to grow since then. So whether or not you like it, the users that are visiting your web app or website are on a mobile phone. They are not on a desktop computer. They are not on the laptop that you're developing on your device. But you as a developer, you're like, okay, that's fine, Sam, because I have a mobile phone in my pocket. Yeah, just right here. Well, I'm just going to test my website on this, and it's going to be great, and I will have accomplished everything that you told me to do. But that's not completely complete. That's not the right approach, but what you have in your pocket is a $600 phone. It's the brand-new phone, because you're a developer and you want the best thing, so you have the best thing. But the phone that your users have, well, they look like this as Alex touched on. These are the low-end phones. These are the phones that you get for free when you sign up for a cellular plan. These are the free phones. These phones have a gigabyte of RAM. These phones have a single core.  On the average Android device that checks in, they have, on average, a gigabyte or less of RAM. So not great. And this has some real performance implications on mobile websites. Believe it or not, the average load time for mobile sites is 19 seconds. So from going to the URL in your browser, to that actually loading in your phone and being interactive, that's 19 seconds. 19 seconds that your users have to wait. Now, you've seen this graphic before, I'm sure, but it's really important to think about. Because the web that we're shipping today has a 19 second average load time. And the users expect when you just ask them casually, they expect a page to load in two seconds. And most users, if that site takes longer than three seconds, they'll just leave the page. So that web app that you're delivering right now, if it takes longer than three seconds, throwing away half your traffic. Okay. We have 19 second load times. We are shipping experiences that don't match what users want. So how do we align the web that we're building today with what users want? To do that, I think it's important that we take a look at what it takes to load a web page. From when you issue the request to when that page loads in your browser and when you can interact with it. What exactly happens between when you hit go and it shows up? So I've taken the network stack and everything that happens in between and simplified it down, because it's a lot to talk about into three phases. And the first phase here is requesting the page and the server getting that page and then shipping back an HTML document to you. As I've so beautifully illustrated here for you all, this is what it looks like. You go to the website on your phone, it hits the server. The server then generates a document and has to do some processing work to figure out what exactly we're going to send to you. And then it ships that document back to the browser. And don't forget, that request has to go across cellular towers and then find its way through the internet to the computer that's responding and then when it gets it, it has to send it back. And so that round trip cost on mobile phones, it's real. All right. Now we have the document. The server has responded. So the browser has to do some work now. We have to parse the HTML and we have to figure out what exactly is required on this page for us to actually show it. So we have to find these critical assets. And once we've found these critical assets, the browser says, okay, I need this JavaScript file. I need this style sheet. I need these two images. And when I have that, I'll be able to draw something that I'm not sure about. But we have to issue requests for those. And those requests go over the wire through the cellular towers onto the server. The server figures out what exactly we're sending to you. The server then responds back. And all of this takes some time. So all right. We have our high priority resources. We've made that initial connection to get the document. And here we are in my favorite phase. The parse and execute phase. We have the assets. The browser isn't showing you anything yet because it actually has to compute what all of these individual pieces look like when they're combined together. So we have our HTML, our JavaScript, our CSS. The JavaScript parses and compiles so it can actually be evaluated by V8 and Chrome. It runs some JavaScript. Maybe it adds some DOM onto the page. The browser then tries to render. It takes your styles. It calculates where all the positions of all your elements. It lays them out and then it composites any layers. And then you end up with a beautiful page. But this is just the loading phase. This isn't interactive yet. This is just getting something on the screen. All right. Given all that, I think it's important that we take a look at this network phase. If we're going to optimize one layer to start, the network seems like a good opportunity because we're issuing requests to the server. The server has to respond. The server has to respond to requests. And there's a real cost here.  I started out with a pretty simple baseline. I didn't bundle any of my assets. So I have individual assets for everything, not one big blob. I then set up an HTTP2 server and I simulated a 3G network that I tested this on. So we got some real-world sort of metrics. So let's take a look in DevTools how we can get a feel for what this is like. All right. So here's shop on the left and here's our recording that I've done before and saved this off. So you'll notice I have this pane up here, which you might not be familiar with. This is the network view. Network view is usually hidden away and you check this box. And then you see this beautiful waterfall of all the things that are getting downloaded. And you might be saying, what is this gray line? I've never seen that before. Well, of course you've never seen it before because the patch line did yesterday and I have it right here. So what this means is this gray part is we're just waiting for content. We haven't gotten anything. The request went out but we haven't taken any action yet. So you can see that in this case it takes 1,500 milliseconds until we actually get a response from the server and then we're downloading the content. Okay.  Okay. So all of this results in a paint that takes around 5,500 seconds... or milliseconds. Okay. So 5 seconds, 5.5 seconds for this on a 3G network. It's not terrible. It's nowhere near that 19-second average. So we're starting off from somewhere that's not horrible. However, as a developer we can see like clearly there's some room here for improvement. Yeah. So again, I'm just holding down shift here in the timeline as I drag, I can actually measure how long. So right. So 5,500 milliseconds roughly between when we got our first bite from our server to when we rendered a screen. Now shop paints something pretty quick. We have this frame up here so the shop, but really that's not useful to the user until we actually have content. So this is the first content full frame or the first meaningful paint and this is what I like to measure till. So we see we get these network resources.  All right. So HTTP 2, no bundling 3G, 5,500 milliseconds until first paint. Okay, let's look at some techniques that we can apply here to drive that number down. Now I don't know if you've heard of this really cool feature that's in Chrome called link rel preload, but what this does is it allows you as a developer to basically say I know exactly the things that my page is going to need before it's displayed and loaded and so what I'm going to do is tell the browser what those are and the browser is going to see this and say, okay, I'm going to download these. I know you haven't requested them yet, but like I know something as a developer, you're like something is going to request these, so just start. So the browser will download these. They will sit there and so when your browser finally issues a request for them, it's like, oh hey, I already have this, so you don't have to hit the server again. So I took the site, working off of our base with no bundling going on and I looked at all the assets that were required before we actually issued a paint and so I did link rel preload, put it all in the head tag and let's see what the effect of this is. Oh, so this looks quite different. It's now very flat. We no longer have this sort of stepping effect of dependent resources on dependent resources that eventually resolve into a painted page. Instead we just have a flat line of things. It's like, hey network, just grab all these. Thank you. And then when we have them, we end up with a paint. So from our first bite here to when our first contentful frame was, we're down to 3,300 milliseconds. So we've cut out two seconds roughly. Just by avoiding that network work of having to download, discover, download, discover, download, discover and flattening that out. Now you might be thinking, okay but like why would I ever have a site that was daisy chained like that and have all these dependent resources and this is totally contrived. Fair point. But on your site I guarantee that you're downloading fonts. I guarantee that you're downloading JavaScript. If you're taking advantage of some of the new module splitting features of build tools you probably have lazily loaded JavaScript files. And those are all late discovery documents. So what you can do is you can use link rel preload to sort of say hey start downloading these because I'm going to need them. Which can be a real win and in this case a massive win. Alright we're down to 3.3 milliseconds on a mobile network which is good. We're getting closer to that two second time that people want but we aren't quite there. And we still like if we look here we have this cost that's kind of crazy like we have this initial connection cost which is 5 seconds which is insane but then once we finally get a bite we're spending you know essentially 1.6 seconds just downloading this document and we're not taking advantage of the network during this time we're saying give me this HTML document please give it to me thank you I'm receiving it and then once I have it I download more stuff it seems like a wasted opportunity like it'd be nice if we could jam some requests in here as well turns out there is a solution for this a solution is called h2 server push how does this work what is this well it's the basic idea that your page when requested from your browser it hits the server it opens this connection the server as like while it's responding with html the server says I know you're going to need these assets so I'm going to go ahead and push them to you you didn't ask for them the browser has no idea that they're coming but I as the server know the world so here just take them and when you finally need them on the client side well they're already there this compared to the previous approach that we were doing which was two round trips which was get the document scan the document request all of the critical assets and then we can paint so in this case the server is pushing the assets to us it changes who's responsible for what now you're probably like I read a blog post about h2 push and that blog post told me lots of things that were not so great about h2 push and I probably read that same blog post so let's talk about them because it's important to h2 server push it's not cash aware what does this mean well this means that the server doesn't have an idea about the state of your client so if you visited the page before and you have these assets cached the server it can just say hey I'm going to push main.js again because I don't know if you have it and by pushing it the client's unable to cancel that right now and so it causes this network contention and can cause a real cost to your users because you can basically push everything that you want and the browser's just going to take it so not great and can actually slow down your page quite a bit the second is that h2 push doesn't have resource prioritization alright what does this mean well it means that the browser natively is pretty smart about what things it requests because it's able to determine that like this is critical this is not critical I can defer this work and so it tries to optimize for its network activity h2 server push is like a bully it just pushes it to you you don't it's like here just take all of it and the browser's like okay I'll take it so it's not so great but there's a solution for this which is kind of the first P in purple it all revolves around this one idea it's that h2 server push plus a service worker is like this nirvana it's a magical thing because it avoids the big downfall in my opinion of h2 server push so let's step through this so we can understand it on our first load the browser requests to our server the server then pushes the critical assets and at the same time delivers our document our document is then scanned by the browser the browser says okay I need these files go out and make the requests but oh you already pushed them to me so I don't have to hit the network great now on your next load you have installed your service worker as represented by this beautiful green square with the letters SW the page you go to your page but it doesn't even hit the server it hits your service worker the service worker intercepts this request and it says hey I have index.html so here you are and oh you want these assets too well I have them cached as well and what this avoids is you are not even opening a connection to your server so because you have not opened a connection to your server the server can't push you things that you don't need so by combining h2 server push plus service worker you can get all of the benefits of that first load with h2 server push and avoid the majority of the downfalls of getting pushed assets that you already have cached so this is really good so let's take a look at what shop looks like if we actually used h2 push and this is the default thing that the shop site actually uses which is really awesome so here we are we have the site this timeline looks really different so it looks like we are still paying that really high cost here to get our initial page and we are still spending 800 milliseconds or more inside of that initial request and then we see this very interesting sort of representation of what is going on and what you are seeing here is actually the files being pushed to you from the server now these in reality are probably being pushed out here but right now it is shown just right here which is fine so we look we see we get all of these assets that are sort of sticking around they are all marked as lowest priority then we scroll down and we start that wrapper element that root element that shop app html we see the moment that this is finished right here being downloaded we then fire off all these requests but you will notice that these requests are really fast 63 milliseconds 78 milliseconds 62 milliseconds how are we doing that well it just so happens that these are those assets right here when we request them the network says hey do I have this go into the network stack of chrome network stack of chrome says why yes you do here they are in my cache please take them which ends up making for a super super fast experience and we can see from first byte here to when our page actually renders we are under 2 seconds which is amazing so we went from 5.5 seconds to 1.7 seconds and we are now on a 3G network for our initial load with no service worker installed so that's pretty impressive alright what did we learn network takeaways link rail preload what is this good for and when should you use it well it's good for moving the start of downloads earlier during that page parse so the browser parser can instantiate those requests before the browser knows that it really needs it as a dependency h2 push when you boil it down it's good for cutting out one full roundtrip to your server so the most optimal delivery of h2 push is you are going to save at max one full roundtrip and that's important because when you are measuring your site and figuring out where to optimize you want to optimize your biggest cost and so if your latency that exists for a roundtrip is your biggest cost well congratulations because you are in a minority because that is amazing and h2 push is probably your solution alright we've talked about the network cool we know how to get our assets to our browser quickly and how to get that first paint the first meaningful paint pretty quick but paint and that first frame is only part of the story the real interesting bit in my opinion is getting to interactive and the costs for modern websites to get to interactive well it's our friend javascript just sitting there like hey you need to execute me and parse me and on our phones that tends to be kind of slow to understand just how slow this is well we need to look at what javascript deliveries have been like and these are gzip size in november 2010 we were shipping on average 100 kilobytes of javascript pretty good today we're shipping four times that on average 408 kilobytes of javascript on every page load okay so what well there's a cost there there's a cost to shipping this parsed code if we look at some older devices like an iphone 4 nexus 1 our parse time for 300 kilobytes of javascript from anywhere from 300 milliseconds to 500 milliseconds half a second remember users want that page to load in two seconds but you're looking at this and say Sam these are ancient phones this is a terrible graph not applicable to me well remember the phones that your users are actually on are those older devices which are very very similar to these phones listed here but it's fine I understand your concerns because I have a chart for new phones all right four megabyte of javascript because you're shipping all the frameworks all at once on a nexus 5 it's a pretty new phone I like that phone we're at like 1800 milliseconds of parse time iphone 6 with the latest operating system we're at a full second of parse time s7 about a second all right there's a cost here users want it in two seconds you're shipping a megabyte of javascript all that time is gone let's measure this because I can talk about numbers and we can talk about goals but I find it really helpful to take a look at something that represents the real world so I found a cool little app it's a budget app that uses some technologies that you're probably familiar with webpack react, redux awesome, sounds fun so let's load it up here all right, here's our app let's clear this out this is a really good budget app I'm going to say what do I want to buy? cat food great I spent $100 on cat food I got the fancy kind so great I'm really struggling with my guitar and the Trader Joe's food so let's record let's record a profile here and as you've heard today we can enable this CPU throttling which is not a real device but it helps kind of get slower so this is on a MacBook Air yeah sure and we're just going to do a 5x slowdown which should make things slower, not quite a mobile phone and we're going to look at the javascript costs just for the simple site so we'll do a reload command shift R, we record the timeline it comes in, here we are my friend all of our friends really, just this chart okay well what does this mean? well right here we see that we have this bulk of yellow it's goldenrod color actually it's a bad sign it's javascript executing and we're spending this frame 421 milliseconds just handling this so what's our cost here? why is this taking so long? so I click on this frame here which gives me a bottom up view of the javascript here and we zoom in here 140 of the milliseconds is spent in T obviously it's T of course, T oh T, I can't so I'm not really sure what that is but we can find out what T is and looking at this code really isn't useful so I can pretty print it okay great oh there's T, hello T oh I don't really know what this is but I kind of know what it is it's actually the sort of module that the webpack uses but what's strange is this doesn't look like a very expensive piece of code it's not doing anything that's explicitly slow so it feels like the numbers that are reported to me and dev tools are lying to me are not completely accurate this cost is being associated here but I don't think it's actually here yeah so I really think that it's probably parsed time, it's parsing that javascript just from some experience that I've had so we start here, we have this T function but I want to see the parse cost and I know that I could step down into about tracing and click those checkboxes and reload it and then find it but it's hard and it always confuses me so wouldn't it be nice if there was a way that we could see those V8 metrics inside of dev tools I agree well I'm happy to say that in Canary we have an experiment where the metrics are now in timeline which is exciting screenshots are great but demos are better so here we are, let's have a demo great, enable our CPU throttling again awesome let's just reload the page, command shift R wait our 3 seconds okay here we go 4, great good 739 milliseconds that time alright where's our cost oh that's different parse function that's what I thought, parse function compile code lazy, compile full code compile script, function callback these sound like native V8 runtime things excellent alright and we could go into exactly why this cost is there but there's a lot of blog posts that describe how to optimize and this at least gives you a starting point so you can understand the real parse cost of your website okay but parse time that's part of it but you have parse time because you're shipping javascript and so when you're shipping javascript it's really easy with npm just to require everything and then say okay great it works so it's never been more important to actually understand what you ship webpack recently had a plugin released it's called the webpack bundle analyzer and this actually shows you what's in your bundle your webpack bundle and you can explore this tree map and see the gzip size the bundle size everything great about it you can find out why you have three versions of jquery on the page to improve things and then for those of you using browser fi there's a similar tool called disk which has a sumburst chart which is beautiful I'm always so happy when I see this I'm able to find disk size etc same information and understand what you're shipping you're shipping less code ideally but you're still having that parse cost and you have to think well the only way to shrink parse time is to ship less parse code okay well how do I ship less parse code because I'm shipping javascript and I want to be parsed that's a good question well there's two techniques that I like pretty simple to do you know the script tag it always has that type on it when you set source well you can change that type to be whatever and if it's invalid and the browser doesn't know how to handle it it will download the script file for you but it won't do anything it'll just sit there and so you can put type inert type poo emoji it all works you'll get that script tag and then what you can do as a developer is say oh I have some idle time here let me go ahead and evaluate this javascript take the contents put in a script tag this gives you control over when the parse time happens so ideally not at that initial boot up experience now you can also have another script tag where you wrap your code in comments okay so you ship down javascript that's commented out but then when you want to evaluate it you just strip those comments out and then the code is now evaluated so some techniques for manual shipping of inert code you need to avoid that parse cost which is non-trivial alright that seems pretty manual it is wouldn't it be nice if there were ways to do this automatically in my framework of choice and there are the community has been listening and solving these problems for you so it's much easier to do these things Angular 2 actually ships with lazy module loading by default ahead of time compilation so you can do per route javascript bundle downloads pretty remarkable Polymer CLI which built the shop site has per route fragment sharding so it's aware of your page and all of your routes and it's able to say I know that this bundle is going to be for this route and this one is for this other route and so here are these independent bundles that you can download when you feel like you need to the other way is a little more manual but still really amazing Webpack has a plugin called aggressive splitting plugin and it redefines the semantics around require to add require.insure and what this does is it essentially builds a dependency graph of your requires so that Webpack can say okay I'm going to split this JavaScript bundle, this one, this one, this one, this one this one and you get like a lot of JavaScript files but they're great because they're really small and you can manually control when you download them which is so awesome all right so we looked at network we looked at JavaScript and we looked at some of the tools and visualizing it and measuring our cost so what do I want to leave you with well as you've heard time and time again today it is a mobile world it has never been more important to test on real devices not the one on your pocket the one that your users are experiencing your Web site with and it's not just testing on a mobile phone it's also testing on a mobile network You need to go and you need to go get a 3G network and say, okay, here I am on my phone on a 3G network. What does my web app feel like? Is it slow? We should probably fix that. Now given what your users visit your site on, it's critical that you optimize for network utilization by using techniques like service worker, link rel preload, HTTP to push. These things can help you get super fast first loads in under two seconds. And on reload, it's instant because you have that service worker just sitting there. And finally, my favorite, it's a JavaScript parse cost. JavaScript that you ship has a cost because it has to get evaluated. It has to get parsed. So when you ship more JavaScript, parse time goes up. There's no way you can really avoid this. So the trick is you ship less JavaScript. You ship less parse JavaScript. The end result of all three of these is that your users have a blindingly fast web experience and everyone wins. Thank you very much. Well done. You made it through, buddy. So happy for you. Go and lie down now. You did well. Well done. Well, our next speakers are here to talk about predictability. So expect the expected. Please welcome to the stage, it's Rick and Robert. Hi, everyone, and welcome to our presentation about predictability. But first things first, we are Rick and Rob, which kind of sounds like two cops on stake out. But just go with it. And since I got the opportunity to put together this slide, I got to pick which picture to use of Rick. This was the best picture that I can find of Rick. Thanks a lot. This is Rick. Hi, I'm Rick. I lead a team of software engineers working on the web platform. And my name is Robert, and I work with developer relations around feedback and community and then much more. This is the worst picture of me available on the internet. Don't check. And the things that we're going to talk about today is what is predictability? You've heard many interesting talks today about new features and all the progressions that are happening on the web. But what we believe we're covering today in this talk is the most important thing. And that's having a reliable platform for developers. If we don't have that, we don't have anything. And web developers love the web, right? Well, so-and-so, right? There are still a number of issues and challenges that developers come across. So we want to be honest about this. This is an uplifting talk at the end of the day. We want to be honest about this. The web does have a problem. Working cross-browser has historically been really, really hard. It still has a number of challenges. And also with inconsistencies between different browsers, interoperability between different platforms and devices and all that. So we want to make it better for you so we have one joint web platform. So that's why we started the predictability project about six months ago. And maybe you've been working with square wheels so far. But we see this as our responsibility to make sure this is actually good for you and expected you could spend the time on the right areas. And we put our most neutral people working on that. So I'm Swedish, Rick is Canadian. So basically you can complain a lot to us and we'll say we're sorry to see the theme here. And actually thinking about the team, we have a number of more Swedes and Canadians on it, so this is not a coincidence. And the main areas we want to go through today is how Chrome is trying to improve predictability for developers. All the work we're doing to make things better and, well, more predictable. Also how we work with other web browsers to make sure it works the same way across the board. This is not just about us. This is about the web and how we do things together. Having browsers fight against each other is just a waste of time. The important thing is the web. And finally it's about how web developers, how you can help improve the platform as well. Basically we want the web to just work for developers. That's it. And it shouldn't be that hard, but there are some challenges around that. So there are five main areas where we want to address this. First, we want to make sure that you fight the platform less. Less need for browser-specific code paths, making sure you don't have to have too many work arounds for regressions. Basically things that used to work and then three months later it just stops working. You have no idea what happened. Also trying to get away, diminish or even just completely get rid of all kinds of polyfills and shims and all that just to cover up for interability. That's not the way it should be. We also want to make sure that we don't chip any accidental regressions. And when we deprecate features, we really want to understand that we're knowing what we're doing and what the cost is for you. How will this affect you? Not just like, yeah, I never liked this API. So we want to make sure you actually know what's going to happen. We also want to be way, way more open about interventions. And Rick is going to cover interventions more later in his part, but basically giving you options to, well, solve issues when that happens. But to be honest, things do fail fast in the world. And when it does fail, we want to make sure it's both fast and obvious to you. So it's not just a complete surprise every time you have no idea what happened. It's also about having quantified data and, sorry, analysis to make sure that we know that when we cancel different features, we have the numbers to back it up. How is this actually going to affect developers? And finally, just giving you a more coherent platform, making sure that the most commonly used features work really, really well together. Like, we want you to feel this passion, right? If you look in their eyes, they love the web. Slightly scary, but still love. OK? And working on the web might have been hard historically. You might still have some issues. But moving forward, we want you to look back when it was hard and just laugh it off. You're just going to be happy because working with the web is going to be a breeze. That's where we're going. And to go more into detail about that, we have the amazing Rick. Thanks.  It's a big dream. We've got a lot of work to get there. But I want to get a bit more concrete for a minute. It's always been part of Chrome's mission, as you heard Darren say this morning. It's always been part of Chrome's mission to make the whole web better. Not the web shouldn't be just a collection of browsers that kind of behave similarly. But we really realized over the past year that we've got more to do here. In fact, first and foremost, we need to collaborate better with other browser vendors. In fact, part of the reason this project exists is because we were really inspired seeing how hard Mozilla and Microsoft were working to make their browsers just work for the websites that you have already built rather than trying to get you to change your websites to make them work on their browsers. And even when that required copying some buggy, non-standard stuff from WebKit and Chrome, it sucks that they had to do that. But it was inspiring and it made us want to invest more in this space. And so there's all sorts of ways that we've been working better over the past year as a community, as a browser vendor community. I'm not going to go into all the details here. It's probably kind of boring for you. Standards are obviously a huge part of this. We invest a lot in the standard process. We care a lot about standards. But even the day-to-day of how we do browser development has really changed. We're constantly filing bugs in each other's bug trackers. We're constantly collaborating on shared test suites. It's very different than it was a few years ago. But I don't think that's too relevant to this audience. I think probably the area you care more about is it's really important that we do a better job of listening to you. And honestly, this is why I'm here. I'm hoping this will be the start of a conversation. Hopefully, somebody will grab me afterwards and complain what's bothering you about what makes the Web hard for you. And this is important because I think the Web is unique in that it's the commons. We all own it collectively. No one controls it. It's really a marketplace of shared ideas that compete against each other. And in that kind of environment, it's essential that the different players in that ecosystem are talking with each other and understand each other. All right, so typically the best way for you to tell us that we're doing something bad is to file bugs against us. For those of you that don't know, Blink is the web engine underneath Chrome, Opera, and Samsung browser. And so I'm going to talk a little bit about Blink bugs, bugs in our web engine. Over the past year, we've really invested a lot in bug health here. We realized we had a bit of a problem. And so now, I think we've got a really good process where if you file a bug on us, it first goes to a QA team that tries to reproduce it and they'll engage with you and try to ask some questions. And then once we can verify there's a bug there, it gets routed directly to an engineering team. Pretty much we have complete coverage now of all of our bugs so that there's some team responsible for checking on the bugs regularly and trying to prioritize the most important and working with you to get fixes. And as a result of that, you can see over this past year, for the first time ever in the history of our project, we've consistently closed more bugs than we've opened, which it's always a good place to be in. APPLAUSE Thank you. Good. And here's some stats. I just picked September. Bugs filed in September by you all. These were bugs that were filed via our wizard, so people that aren't Chromium committers. There were 300 such bugs filed in September. And already 93% of those have been reproduced and routed to an area. And that's what we mean by triage. They're on some teams plate to deal with. About two-thirds of them have been resolved in some way. Sometimes this means, actually, it's not uncommon that we dig in some issue, we talk with people, and we agree that actually turns out it's not a bug in Chromium. It's a bug in a website or a framework or something like that, and that's fine. Or sometimes it's a duplicate of another issue. And about 16% of the bugs that were filed in September turned into actual fixes that have landed in the code are now shipping in Chrome. And I think there's more to be done here, but I think this is pretty good. I think this is a signal that if you file a bug on us, there's a good chance that the right people will see it, pay attention, and something will happen. I think it's worth your time. The other signal that's really valuable to us is our stars. You can see in our bug tracker system here, there's little star next to the issue. If you're signed in and you click on that, it means that you care about this bug. You want to get email updates. And we use the number of stars as a really important signal in prioritization. We know it's flawed, it could be gamed, so it's not the only signal we use, obviously. But if you look at the stats for just the top starred bugs, the top 1% in terms of stars, we fixed 2 thirds, which I think is fantastic. And that's true for the entire lifetime of the project. It's also true if you just look at all the bugs filed in the past year, the top 1%, 2 thirds have been fixed. And that's fixed. That means it fixes landed, right? Some of these weren't actually bugs or some of them were other things. In fact, I'm particularly proud that if we look at the top 60 starred bugs of all time in Chrome for web platform bugs, we've fixed nine of them in the past year. And many of these are things that you may care about. You'll notice there's two on this list that have three-digit bug numbers. That means these bugs were filed the day the Chromium project opened in 2008. So we're a little slow getting to them, I'm sorry. But we're on top of it now. I think we're also getting a lot better at involving all of you and listening to all of you in terms of new API design. Google, now when we work on new features, we will initiate new web platform features in a process that we call incubation. That is a process that really emphasizes starting with use cases, not starting with a solution. Starting with use cases and involving web developers, trying to vet that these use cases make sense and that the ideas we have for them solve those use cases. And we do all of this in the open via the W3C's Wiccig group, the web incubator community group. All of this is on github.com. Take a look at the repositories there. There's an explainer document that describes the problems that we're trying to solve. And there's often draft specs. And we love to involve you. File issues, tell us what you think. And then when it comes time for us to ship a new API, this is a really important time for us because we want to balance, like it's our mission to push the web forward, but we want to push the whole web forward. So the most important signal for us here is what's the interop risk? What's the risk that we're going to regret shipping this because it's going to end up being a Chrome only thing? We don't want to add Chrome only things. We're happy to be able to head. We're happy to push things hard. But we really try to get feedback from the other vendors. You can see on our Chrome status page here, the colors under each of the other browser vendors represent what signal we've got from them. And you can click on those and get links. In this case, position sticky was something that's already shipped in Firefox. A prefix version is shipped in WebKit and it's on the Edge Roadmap as priority medium, I think, meaning that they intend to work on it. So that's like a really strong signal. Position sticky is something that's going to become part of the web everywhere. And at this stage, we get a ton of feedback from the other browser vendors too. Microsoft and Mozilla in particular, we discuss this trade-off in public on our BlinkDev mailing list. And when they don't like what we're doing, we hear about it and we will delay shipping things to try to resolve outstanding issues. All right, and then once, even before an API ships, it'll show up behind this experimental web platform features flag. You can go to Chrome flags, turn on experimental web platform features and play with the APIs that are coming up. Of course, we've got Chrome Canary, we now have Chrome Canary for Android, updates basically daily, so you can really try out the bleeding edge stuff, file a bug, and see how things change day by day. All right, the third main area where I think we've gotten better over the past year is that we now have better tools and processes for minimizing breaking changes. So first of all, how many of you have worked on a site where a new stable version of Chrome has come out and you've had a big emergency because something's broken on your site and you gotta do something about it?  All right, okay, not quite as depressing as I feared. I'm sorry, I apologize. We definitely don't wanna do that, but I can't promise that we're never gonna do it because it's fundamentally incompatible with our goal of pushing the web forward. The only way to never break anything is to not move. And so we're trying to be thoughtful and strike a good trade off here. And in particular, I think we've gotten a lot better at minimizing those cases. Let me give you some examples. This is a specific example that's pretty recent that I think highlights how things should go when they're working well. So this was, in September, a developer noticed that they were just using Chrome Dev Channel and they noticed that on their site, their input type equals range element wasn't behaving correctly. And they actually figured out that it had to do with a particular CSP rule they were using. That if they hadn't figured out that it would have been fine in this case because the most important thing is when they filed the issue, they told us that it was a regression, that it used to work in Chrome 53. And that was an important signal for our QA team. The QA team said, okay, great, we're gonna go do a bisect. That means we're gonna binary search through all Chromium builds between Chrome 53 and then and identify the single commit that broke this website. And you see that happened within a day. The next day, QA team had done that and they had identified one particular Chromium commit, which is great. It means that we can make progress on this issue right away. We know who to assign it to, the developer that landed the change. And we know one possible fix is to river that change. So this cuts out a lot of the uncertainty that we used to have in our regression process because we don't have to try to point fingers and do a whole bunch of debugging to figure out why your site's broken. So in this particular case, what this meant was the bug was introduced back in August and no one noticed for almost a month. And then after Chrome 54 beta was released, this developer filed the bug. Within two days, a fix had landed for it. Within a few more days, there was a new beta release of Chrome 54 that had the fix. And by the time Chrome 54 hit stable, the fix was in there so it didn't affect any users. This is how we wanna see regressions happen. And this is fairly typical these days. So if we take a look at those bug stats I posted before and extend to logistic regressions, you'll see the numbers are even more promising. 100% of the regressions that were filed in September have been triaged, 85 have been resolved, and 40% pretty much have had a fix landed. All right, but unfortunately, breaking changes aren't just about accidental regressions. We believe that it's important, in order for the web to be able to move forward, we believe it's important that there's some way to shed the mistakes of the past. But this is something that we wanna do very carefully and very thoughtfully. We take it very seriously. We really don't wanna break websites as a result of this. Try to balance what's best for the platform overall. Let me give you a concrete example. Any time we're thinking about maybe we should break some functionality intentionally in the web.  So in this case, the security team made an argument to us. They said, look, geolocation API returns precise position. When users say yes to that on HTTP, we don't think they really understand that they're not saying, yes, I want this site to know where they are, where I am. They're saying, yes, I want everybody that's sniffing to the network traffic to know where I am. And we know that's often a fair number of people. So they argued that we should make geolocation behave as if the user always clicked reject if you weren't on an encrypted connection. And so we said, okay, well, let's look at the stats. So if you've opted in to anonymous data collection in Chrome, then we send this anonymous data back to Google that we can look at. And we saw that 90% of geolocation was already being done over HTTPS, and the remaining 10% accounted for about 0.05% of page views. This is still higher than what we'd normally like to see if we're really gonna break something, but weighing the trade-offs, we weigh the trade-offs in public again on our Blink dev list. We solicit feedback from various parties. And in this case, we decided that, yes, it was worth the cost to break this scenario. And so we have a console warning in dev tools to say, warning, you're relying on something that's gonna stop working. We're working on a new API, so you can get this from the wild rather than just having to use dev tools. Normally these days, this will always include a milestone and a date for when it's actually scheduled for removal. But then after some period of time that there's been a warning and we've got a blog post explaining that there's gonna be a breaking change, we'll eventually rip it out. And then we go through our normal launch process, right? We've got Canary, Dev, Beta, Stable.  All right, so it's still really hard to build a website that provides a great user experience, while also being built out of components that you don't necessarily control. iFrames, ad networks, third-party scripts. There's a fundamental tension there. And if you think about this, this isn't new. Browser vendors have always made a trade-off. The browser is a user agent, right? It's designed to mediate between developers and users and sometimes act on the user's behalf. Most classic example is pop-up lockers, right? All browsers have some heuristics in them to decide when am I gonna allow a window dot open to succeed and when am I gonna say nana?  And this is a really tricky trade-off. We've always struggled with this because on the one hand, we want the platform to be predictable. We want you to be able to reason about what's gonna happen, but finding the right trade-off for these sorts of things is tough. So over the past year, we've gotten a lot more disciplined about how we approach these types of difficult trade-offs. We formalize the concept into a term intervention. An intervention is something that minimally breaks existing behavior in the browser in order to get some substantial user benefit. And good interventions should be predictable, meaning that you can know when it's gonna happen. It's something that we could standardize. We will be on a track, hopefully to eventually be standardized. It's avoidable, which means if you're following best practices, like using HTTPS for anything that's privacy sensitive, then you won't be impacted at all. It's only really for things that we consider legacy. It's transparent, which means that there's APIs so you can measure and understand how often you're being impacted by an intervention in the wild. And critically, it's justified by data. We're constantly collecting data from the field to evaluate the cost-benefit trade-off of interventions and try to strike the right balance for the overall health of the web. Let me give you a concrete example. In Chrome 52, we shipped an intervention called, where we throttled the rendering pipeline for off-screen cross-origin iframes. Basically what we realized is there was a lot of sites that were using a lot of CPU for updating animations of ads that weren't even visible. And we're like, well, that's silly. But that was how the web was designed, defined to behave, like request animations frame and supposed to fire whether or not your iframe is visible. So we did a bunch of investigation and looked at what some other browsers had done in this space. And we shipped an intervention in 52 that showed substantial power improvements. On a bunch of sites, if you just leave the page sitting there, power usage went down by 50%. In some cases, 90%. And this was kind of an ideal intervention in that when we shipped it, to this day, we haven't had a single report of any site being broken by this. It was theoretically possible that some site could have been, but this was a great example. We saw a huge user benefit for very little cost. And there's really a theme here. Thanks. There's a theme that we're trying to do more to protect the top document, the main application, from iframes that might not be well-behaved. For example, we're trying to extend this to also include timers. So set timeout doesn't fire. We found a couple cases of that spraking. We're working with people and trying to mitigate that before we ship that. Again, we're designing all of this in public. We think it's important. This is about the web, which nobody owns. And so we think it's important to have these trade-offs be public discussions. Again, we do it via the W3C's WCAG community group. There's a repository called Interventions, where each of these ideas we have is filed as an issue. And we'd love your feedback on them. In particular, if you've got a concrete example of where your site is being impacted, maybe it's a scenario we didn't anticipate. Maybe there's a way we can change the design so we can get all the benefits without actually hurting your site anyway. So we'd love your feedback here or just file bugs on Chrome again. All right, Dr. Robert. Hey, what happened to Amazing? I called you Amazing. Sorry. We rehearsed it, right? Well, OK. So back to the high-level guy, I guess. So of course, part of predictability is also working with developer feedback and listening to you. And the three main areas are, of course, hearing what you have to say and acknowledge the issues that you're facing, also understanding different challenges that you have, and finally also getting information from you, getting data, getting use cases and all that to make things better. And one part has been improving the bug wizard for Chromium. So Q and other stock photo or bugs. But the general idea has just been to, with the bug wizard, make sure that it has a very clear web developer focus right now. And also that if you file a bug, we can have a direct routing to that team, fixing that specific issue. So the way it looks now, you would come in and you would pick WebDeveloper. And it's a very clear view from you.  Whereas before, it was a long list where most, if not all, of these were completely irrelevant to you. So we're just trying to make it slightly easier for you to go through that path. We also want to talk about services like Browser Stack, where you can quickly get screenshots from many different browsers and devices, even those that you don't have, but just to see what it's like across the board. So for instance, you can test your stuff and you can see what it looks like in IE 11. And then comparing and seeing with Opera 12.15, this is the same experience. And then what about the iPhone 6? Does it work there as well? It's just a really easy way to at least get an impression and a perspective of what it should be across the board. Also, interestingly, they offer the way that you can use your browser interactively. So you can pick one in that list and you can go in and you can try Safari or Chrome on iOS, for instance, and you can see what it's like in there as well. So services like Browser Stack and Sauce Labs and other ones, we really recommend checking those out to get a good overview. And we can't stress this enough. Filing a good bug or starring or contributing to an existing one is definitely the fastest way to get an issue fixed. So we can resolve the challenges that you're facing. And also as part of this, in our website, we're launching a new feedback section where we will surface a number of ways for you to, well, give feedback and also getting involved earlier on and try out new different things as well. Because engineering for, well, basically any browser is being handled by bugs. It could be things that aren't working or feature requests or something like that. And we also want to teach you or help you in how to file a good bug. So there's also information here how you best described your issue to make sure it gets resolved and also how you can create a minimized test case and then host it somewhere so you can share it with us. So we also want to foster discussion. We want you to be able to talk with each other because you never wanted to be like the poor Denver coder that disappeared and was never found again. So the main idea here, and we have some information on the feedback section, is just about, you know, share information, help people or share the issue that you're facing because, you know, being silent on your own and upset won't help anyone. So please take part and contribute. And also, as Rick was talking about, like many of the bugs that are being filed is by our own engineers or between different browser engines. And since everything within development is still driven by bugs, we wanted to make it way, way easier for you to find bugs and seeing what it looks like. At the same time, we want to present the web as one joint platform. We don't want it to be able to or having to hunt down every bug in every tracker everywhere, so we want to present it in one joint interface. So I started thinking about this, how we could do that and we're Google, so we kind of like the idea of searching for stuff and also getting it in one interface. So I presented my ideas to Eric Bidelman on the team and sort of describe what I wanted. He had a few questions for me and then he started hacking. So he created something that we officially nicknamed the BBS, which is the browser bug searcher, and when I saw it, it was bliss. It was fantastic and it was just the way it should be. So as part of the new feedback site, we now have the browser bug searcher as well. We got good help and input from other browser vendors as well, how to interact with their browser bug trackers and getting information from them as well. And why it's so important to search for existing bugs is that last month alone with Blink, 25% of the bugs being filed were duplicates. So please, please search before you file something. But with that said, it's always better to file a bug than to not file a bug. So if it's a duplicate, it's not the end of the world. Make sure to share information. So this is a shiny slide. Do you wanna see a demo? So we'll try and do a shaky demo. Well, don't clap yet. I appreciate it, but no. So, how would we get this here? Is that you? Yes. Perfect, thank you. Also like they were kind enough to make the cursor really, really big for me here. Could we get it? I have a nice view here at least. So the idea is that you would go in here into the new feedback section of the website and you would have this field and then you can immediately start searching for something. And what you get presented with is a list of bugs across all bug trackers. So both where they are being reported, across WebKit, Chromium, and also Mozilla and Edge as well. So basically all the major web browsers. You can also see the current state of these bugs are they being resolved, won't fix, are they just being new and filed or something like that. So it's just a really, really quick way to get an overview what's happening. And you can also easily page between different results here, or you can choose to see all the results. And also in this separate page, for instance, if you wanna filter only on a couple of trackers, you can do that as well and just compare those as well. Or just fade out, fix the issues. So you only find the actual relevant ones that are still working right. This is pretty cool, right? Now you can clap. So we had a little backup video in case, you know. And also what I wanna say, tomorrow afternoon at 4 p.m. we're gonna have a breakout session about web predictability. And it's the only session with the welcoming of come there and complain as much as you like, okay. Come and why and come and tell us about your biggest issue because we need to fix this. We need to make this as good as possible for you. So summarizing all this, we are really trying to treat the web as one single platform, the way it should be.  It doesn't matter for you if things only work in one place and not the other one and or which browser's doing right or less right. It has to work across the board. So also please keep on testing on beta releases, file bugs, star bugs for features so we know what you're interested in or need help. Go and visit the new feedback section, try out the amazing browser bug searcher as well. And finally, get involved. This is your web. And we wanna end on a note of saying thank you. The web would be nothing without you. We're doing this for you so you can create all the amazing experiences for people out there. And I think now and these times more than ever, we need one big joint inclusive platform for everyone. Thank you. Dad. Right. Well, for the final time today. Indeed. After this, there'll be the big prize. The big prize. Later on. We're gonna do a couple of questions, the final questions for the big web quiz so we can get that on the board. And we'll just remind people that we're what we're playing for here. The big stakes. That's, this is showing me that this is frozen up so I can make this work. Yeah. What? Well, oh, that's all to play for. Oh, that's the current leaderboard. That is the current leaderboard. Did you, Paul, perhaps put the leaderboard on in the back and get to turn it off? That's possible. Yeah, okay. That's good. Right. Let's hide the prize and let's go for our first question, our first of the final two questions. Ready? Here we go. Here we go. Of the latest stable versions of each browser, which support marquee? Chrome, Firefox, Safari, Edge, i.e. Check all that apply. This is one of the select many ones. You can take a look at the answers as they come in. Almost were pretty, pretty certain. On one of them it looks like 64% there. The rest of them are unsure. Oh, we've got one that's, a few of them are creeping over 50%. It's a pretty even split, isn't it? It's a serious one. Chance, should we lock it in? Interesting, that's how you voted. Confidence was high on i.e. I guess as the older of the browsers there, most people thought, well, it's a fairly old thing. Which one's the least confidence edge? Okay, so people say it's deprecated, it shouldn't be there. If you were saying it might be in Firefox, but not Edge, which is interesting. Interesting, it is interesting. So, let's have a look at the answers as they appear. It is in all of them. It's actually all of them. You can marquee yourself happy. The predictability of the web. You know what I mean? We can always rely on marquee. You just had the talk. Right, and let's go for the final question of the day. Which? I'm so sorry, I enjoyed doing the voice. Which of the following are valid return types for video elements that can play type, passing in a mind type? True, false, definitely, probably, maybe, oh, look not so good. So, two of them are very high confidence. Well, there was particularly little confidence. I wonder which one that could be there. Yeah, we have some smarty pants in there. That's interesting. It's like a four, one, two, three. Right, and shall, let's lock it in, shall we lock it? Interesting, so very high confidence on true and false. Yes, the Booleans, I mean that's, because if you're asking can I do something? You would think, you would think. True or false? You would think, wouldn't you? Yeah, that's what you want. You'd be wrong. You would be very wrong. Because the actual answers are. The correct answers as they appear now. Probably, and maybe. I kid you not, I look this open. The only other option you have is an empty string, which is, that's the no. But other than that, it goes, yeah, maybe. The most nonchalant API on the platform. You give me the video and I will give it a shot. I'll do it live. I'm not promising anything. I mean, I'd love to play it. I really would. So, that is our final questions. And after the next session, we will take a look at the leaderboard and see who's the winner and hand out the grand prize. Which, as a reminder to you, is frozen. It's frozen. There you go. Oh, well. Well, you can enjoy the side of the mug. Meanwhile, I'm gonna leave and you can do your intro, sir. Yes, we're going to do the leadership panel. So, I'm gonna get my tablet full of the questions that you've been sending in today. It's awkward to hold these two at once. Right, let's get our panelists onto the stage. We have Tao Tran, who is the partner development manager. Dion Alma, engineering director. Yeah, come on, yeah.  Yeah, so Dion Alma, engineering director. We've got Parisa Tabriz, who is, well, down as browser boss in her work bio. So, I'm gonna go with that. Darren Fisher, VP of engineering, who you met earlier. Greg Simon, engineering director. Alex Komorowski, product manager. Dmitry Glaskov, engineering lead. And Grace Klober, principal engineer. So, let's see what question. I haven't really looked at these yet. So, I hope they're good. We haven't either. Right, so, question one. How many HTML tags are in the HTML spec? No, I can't, this is the wrong question list once again. Wrong with it. Let me figure this out. Too many. Maybe. Probably. Probably too many. Okay, as you say, we have some microphones set up. We've got one here and we've got one over here. If you want to ask a question live for our panelists here, that is something you can do. I mean, we've got someone being very brave. So, I'm not gonna ignore that. Should we take a question from the audience straight away? This is gonna be very tart. Can we get that microphone on so we can hear the question? Here's the question. There you go. This is gonna be a very specific one for such a big panel. But it hits close to home. It has to do with messaging across Google as a whole in particular how it affects Chrome. Hangouts, I use it personally. I use it in business. And the app versus extensions been shifting and fluxing. And recently the extension has broken entirely. We were pulling it off of GitHub because of a feature that was pulled out of Chrome, the docking feature. It seems like a decision that had to have come from a lot of different places that would have affected a lot of users and doesn't seem like it needed to happen as a breaking change. And I'm wondering if you can tell me anything about the process and how something like that comes to be on the Chrome ecosystem. So, I mean, there's no one here on the panel who works specifically on Hangouts, but does anyone want to take a stab at that? I think we can talk about the API in question a bit. Anyone else, feel free to jump in too. But in this particular case, there was an API developed specifically for Hangouts. And oftentimes when you build an API like that, specifically only for a one-first-party application, it's a lot harder to build an API that's gonna stand the test of time and really hold up and, in fact, be implemented well on all platforms. And in this particular case, we were left with the question of, do we try to really make this thing work well, even though it was really only built for a specific application, or do we move beyond it? And the decision was to sort of move beyond it because it wasn't something we felt like we could actually build in a solid fashion. So I kind of wanted to lead on from that question a little bit more. So the things we promote here, things like being progressive, accessibility, working in all browsers, I mean, that is something that we don't see happening across the websites that Google actually produces. Is there something that we can do there? Are there other efforts there? Is that something we can change? Dmitri, do you want to say, as one is from a polymer standpoint, is that something that we can do? I would love to see that changed. I think Google does need to play a larger role in the Progressive Web Apps ecosystem, and it does need to kind of get on the strain. The strain is moving. Tao was telling us all about it. I'm doing all I can to make that happen. And Yal can help me with that too. So that's also a call for help. So if anyone has any, oh, we'll do the live ones, because, you know, we don't have many of these. This question is about promises. I know you've been very happy about promises, but personally I find it horrible. In the next few sentences, are you going to say the word observables? Just a prediction. Actually, I think it's kind of stuck between two different promises, one being trying to become simpler, like not having nested callbacks, and the other one trying to have like parallel execution, like promise all, and ended up being neither. It's kind of really, really complex, this given point in them. Why is it this two different objectives taken in one single thing and complicated? I mean, is it my personal experience? I don't know, but I think it's kind of, it has two objectives and it has not met both. Well, I mean, how have you used async awaits, where you feel like you're writing a synchronous function, but you're using promises? Have you found that's helped the problem at all? I'm saying, you know, you're saying from nested callbacks because you have, then it makes it easier. It doesn't necessarily, right? I think the problem seems to be that if you really try and build that, you're having a sequential execution, right? But you really don't have the if-then kind of structure that you would normally do in the sequential execution. And also, you know, most of the time when you're having multiple execution, you suggest doing like promise all, like building that structure, and anyway you have lost the whole structure anyway. You have to rethink the whole thing, right? I think so, tomorrow we have Seth Thompson speaking from V8, but we also have Alex Russell, who's on TC39. I think speaking to him about that would probably be better than anyone here, if anyone's got anything to say about that. Yeah, Alex Russell, who spoke earlier, he's around this evening. He's a good one to talk to about that. I think personally, as a developer, if I don't find it useful, it's easy. I think that is what you should look at it as an end result. Maybe it's still easier for you guys, because you're designing the system, but... That's a really great feedback, thank you. So one of the questions I have here, which I think has popped up on every time we've done this panel thing is that are there plans or discussions taking place around making progressive web apps discoverable in the Play Store alongside native apps? And it's interesting that that gets a round of applause, because I always think, like, if only there was some kind of discovery platform on the web, if only one company would step forward and make such a thing. But people like their Play Stores. By the way, there was not enough clapping. Don't pity me. But in all seriousness, I think, to some extent, you can look at app stores to some extent as almost a failure that the web already had that piece. App stores were necessary because there was no other way to get these things. And yes, it has become something on mobile that I think some users expected to be there. But what users also expect is that when you tap a link into anything, it will load up that experience. And so I think it is an interesting other source. I'd like to see how, as we evolve these things, what we can do in that space. But ultimately, I think it kind of underplays the strength of URLs on the web that are like, it's super power. I would totally see the point that if you are in an app ecosystem today, it is important for you to, you know, quack like a duck, right? You need to behave like other players in that app ecosystem. So I can totally see it. I think especially as with the improved add to home screen that we were talking about earlier today, I think as these things become more and more, so they fit in more and more like apps, I think users might bring over more and more of those conceptions. So for someone who had like a gains portal, that was their app, so to speak, and then they wanted to mint other apps. So you're in their thing and you want to grab an app. Well, wouldn't it be nice to have the flexibility for use cases like that that makes sense to be able to do that, to have a meta app that can mint other apps and they're like, when we have these nice things with, you know, to put paths and scopes and URLs and sub-domains so we could actually, you know, look at, you know, be able to deliver those types of things. There's a set of other PWA's and then you can, like, go to them and then you can add those to your home screen. That sounds like a pretty good idea. Get Yahoo to build one, yeah. Tau, like, do you hear this a lot from partners wanting this feature and what do you think makes people really want to be in the store? I think it's more about just discovery overall, right? So why not have both platforms be at your disposal? I mean, at your disposal in terms of discovery, right? So I don't think... I think for most people, they understand like the web is great and has the superpower of reach, but at the same time, having another place to have your progressive web app be available is just additive in terms of discovery and especially if people are in a mindset that the first thing they do is click on, you know, the place or icon or the app store in order to discover content, right? It's just about giving people as many opportunities to actually find your stuff. And so on mobile device, it's the place or the app store. I think to some extent, too, like what we shipped for the add-to-home screen first, that wasn't the final thing. We've been evolving that as kind of a bit of a journey and I think we aren't done yet, I guess. We'll take another question from you. It's friendly face. Hello. Yeah, seeing Jake, should I talk about streams? Or surely? Yeah, my question is a two-part or one. I've been seeing throughout the day that Google has a single browser but building for the web. What's stopping it from influencing Chrome and iOS to have service worker or Safari to have service worker? And the second part is extending the add-to-home screen part. Would it be possible to have a direct link saying add-to-home screen when we search for, say, some web apps? And we know that we have a manifest file already, so it would be nicer to say like add-to-home screen directly from the link. Is it technically challenging and why is that not happening? Okay, so the first part of that is like, what can we do about Chrome and iOS? What more can we do there? Grace, do you want to take this one? I think for the iOS is... for the service worker, we... Very limited. Yeah, so... Yeah, I think it's like we don't... we have to, like, using the WK WebView, right? We don't really have a lot of choices. And what we can do is try to influence Apple to put a service worker into the Web... into the WK WebView, so which means all the apps, like a browser-based app on iOS can enjoy it. And part of things, I think, for us to demonstrate how it works well in Android, and then, I mean, we need you guys to build the app using the service worker and the user can see the difference, benefit, and then hope that can influence Apple to changing, adding the service worker into the WK WebView. Absolutely.  Yeah, and there's actually Apple representatives here. It's been really great for them to show up at the event, as well as Mozilla and Opera and all these other folks. So I feel like, you know, if you... I don't know if we have a polymon for them, we can catch them. If you can find them, like, talk about, you know, what you want from Safari. Yeah, this actually came up last year as Chrome Dev Summit on the talk about benchmarks, and really, that's the ultimate benchmark, right? It's like, well, my website runs much faster for users on this browser versus another. That beats any synthetic benchmark out there. I'm going to do one more question from here before coming back to people in microphones. How am I... Oh, yeah, you did ask. Yeah, I can... It was about at home screen from the search base directly because we know that these apps would have manifested some of them. Yes. That's a great idea. Yeah, things like for the search result page, right? So, yeah. We're actually definitely looking into that with the search team. Yeah. Yeah. I'm hoping to see you that soon. Thank you. Thank you. So how might users' expectations of the security model change when a web app is launched from the home screen? Parisa, do you want to take this one? So it feels like a native app, so should it be able to do all of the stuff a native app can do? It feels like a native app. I worry about this, actually. There is a different security model for native applications, whether it's on a phone or any computer, and the web. And there's great... I think that we have an opportunity to merge that experience and actually make it more immersive between native applications and websites, especially on the phone. But most users don't understand the security model differences. You shouldn't need to. Most developers don't necessarily need to. And now we have kind of native apps asking for permissions and websites asking for permissions, and users don't necessarily know which is which, especially as we kind of evolve the UI between these two things. Was the question specifically asking what... Yeah, is there any things we would grant if the app was added to the home screen that we wouldn't, if it was a website? Is there anything that we would infer? Well, one thing we do is full screen. We'll hide the omnibox. That is already happening today, that you do get the durable storage for your smartphone, things like this. So there's a lot of things that are already happening that add to home screen is such a strong signal from the user that they want to engage with the site that we sort of do have some affordances. But there is, like you pointed out, a really interesting line to walk. Yeah, and I think... I don't think of it as like this is less secure, but I mean, you're getting more capabilities and with those capabilities come, you know, risk of abuse. I think I mentioned earlier today that we were looking at auto granting the notification permission when the user goes to the add to home screen flow. And one of that, too, is as these... with the improved add to home screen, it feels much more like an app in many other ways. In Android, for example, you native apps get that permission to push notifications by default. Yeah, and I think this... I don't think you always want to ask. I think there's a tendency to say, well, we should always ask for permissions, but people get desensitized to constantly being asked to grant permissions. And then you've lost any security benefit, but that question was going to be asked. So I think there's a lot of work we're doing into finding out the balance for any capability. And the more powerful it is, I think the more, you know, thought we put into where that balance is, but... I th