 Hey everybody. How's it going? Good? Happy to be almost done or happy sad it's over? Anyway, I'm here today to talk to you about keeping that progressive in progressive web apps. My name is Patrick Kettner, unlike what it says on my badge. Apparently they thought the Chrome team needed another poll around. But my badge is right. I do work at Microsoft despite what my t-shirt shows there. I'm just a conundrum of confusion. It's just a photo I take every year for my birthday. I get these pictures of cakes every year. My incredible partner Katrina, hi if you're watching, is usually here with me. But now over the last year or so she's actually, excuse me, been spending a lot more time at home because we just had our first child. Holden was born. Thank you very much. He's worth the applause. I know I'm pandering a little bit, but he's a really, really cool baby. It's funny when you first have a kid, like your first kid, all your coworkers, all your friends, all your family give you kind of the same collection of advice. They all say enjoy your life while you still have one. Or have fun eating while you can still have time to do it. Or have fun sleeping while you still are able to. It's funny because with Holden, none of that really applied. He's been a super easy baby. He's really cute all the time. He's just happy, literally happy all the time. He's fine now, but he got sick and had to go to the hospital. And he was adorable in the hospital. This is him with a fever and is sick and everything. It's great. He's a crazy happy baby. He's cute all the time. With one single exception, and that's when we go on drives. He hates getting into the car seat. Not so much the drive itself, but being strapped in. He just, I don't know, he doesn't like being not able to move or something and he just freaks out. It's fine when you first bring him home. We literally live a block away from the hospital he was born in. And so we walked home like we didn't have to drive. It took us a while to discover that he hated this. It's fine. And then after a while, I love to travel. And Katrina puts up with me liking to travel. And eventually we grew kind of sick of sitting at home getting a little cabin fever. And so we thought we would pack up and go visit Whistler, which is outside of Vancouver, Washington. I work at Microsoft, so I live up by Seattle. And, you know, knowing that he hated being in the car seat, knowing he'd have to go into the car seat and being a nerd, I do something that I think most of us would do and I'd go and try and find out something online. That's how to make it better. And so I look up, how can I calm a baby? Look at all these different ways that people suggest doing it. That's my first kid, forgive me. And I found this really neat video. The frame rate is going crazy. It's usually slower than this. But it's basically this interesting thing. All it is is a video of dancing kind of dots. And it snaps him out of it like that every single time. And I'm not quite sure what the science behind it is, but effectively just the combination of the contrast and the motion, it just instantly, he forgets why he's crying and he's just like, oh, crap, there's all kinds of stuff. And, you know, he just keeps going. And it literally works within seconds every single time. And so I'm like, oh, sweet, great, got it. Put him in the car, freaks out, show him the video on my phone. Two seconds later, he's fine, passed out. And we go, get in the car, head up to Vancouver. It's a beautiful drive. If you've never been Pacific Northwest, it's where it's at. We have a wonderful day in the Whistler area. It's a great place to visit. We go and see the old Olympic Stadium. That's him still sleeping after getting there. Those dots really work. And, you know, we're there for a few hours. It's been a long day. We get ready to go on to our car. And I strap him in and he starts, you know, he wakes up as soon as I put him in, obviously, and he gets really upset as soon as I do it. And so I'm like, got you this time. Pull out my phone. My phone carrier, I have like free international roaming. I hit play and I get this. And I get this. And a baby's crying. And my partner Katrina is starting to get upset because it's been a good two minutes now where I'm just staring at the phone. I'm like, it's coming. It's coming. It's fine. Just don't worry. And I wait. And I wait. And it's been five minutes, literally five minutes staring at this screen with a baby screaming, getting more and more upset. And Katrina getting more and more upset and me getting more and more frustrated because I don't know about you guys, but as a person who works with technology, especially like web related stuff, when the web fails me, I take it super personally. I'm like, I could have done this better. Something you did was stupid. And you know, the whole time, you know, eventually we were just like, you know what? Whatever. I'm just going to pack up. We're going to go and he'll, I don't know, cry and he'll be fine. And so we just hit the road. I'm just getting more and more frustrated. And I'm like, oh, just 2G completely ruined my day that we had a nice time, but this, my phone is just so frustrating. And then, you know, I started to get, eventually he cried himself to sleep. And I was driving and I'm like, you know, it wasn't like the 2G that ruined my day because that could happen to anywhere. There's nobody, there's, you know, like YouTube can't send everything in like one bit or whatever. It was really the fact that it was 45 megabytes ruined my day. That's the size of this video. And I was super lazy. I went out, I found a solution and it worked really well on my machine on my incredibly fast home internet and it functioned. And I was happy with that, without thinking about the facts that it's shit for a ton of people out there. It really, really sucks when you're in Canada on 2G and you have no way to load this. Sure, I could have like pre-downloaded. I could have done a lot of things to make it better as an end user, but I couldn't have expected that to happen. And so, eventually we get back over the border. Eventually he is able to be calmed down again. We get back home and, you know, I sit down still frustrated with having been disappointed in myself for being a lazy engineer. And so, I do what I feel like a lot of people do is I sit down, I open my text editor and try to make a better solution because we're JavaScript developers so we re-implement stuff. And so I open up my text editor and I open up Vim and I'm ready to go and then I realize that I'm terrible at anything visual. You know, I'm like the maintainer for Modernizer. I can JavaScript around tons of people all the time but anything visual related I am just horrible at. So I'm like, it's fine. It's just a bunch of dots dancing and then I have like, I have no idea how to make that happen. Like I can put a dot on the screen. I can do a basic canvas or something like that but I don't know how to move stuff and so I sit and I wait and I wait. I have no idea what to do. And so Rise Man once said when you don't have a better idea you can buy a novelty domain. That's exactly what I did. And I went out and I bought Hush Little Baby. And in that time that it took me to come up with this hilarious domain name I was lucky enough to put out a tweet on there saying like, does anybody, can anyone explain how to do this? And Sarah Sudayan, and I'm sorry for pronouncing it wrong, Sarah. I'm trying hard though. I said like, oh, you should check out Green Sock. And if you guys don't know, Green Sock is a phenomenal animation library. It's kind of like a jQuery for animation but ignore the jQuery animate part. It's really, really good. It's super performant. It's super fast. It works really great for JavaScript type manipulations and it worked. And I was like, holy crap, I got this whole thing working literally within like an hour. It was less than 6K for the initial rendering and the initial animation. I lazy load in like an MP3 file. So it gets up to like two mags or whatever. But that's fine. And it works incredibly fine. I did a service worker obviously because I didn't ever want to be stuck in Canada with a crying baby again. And it's a super simple service worker. This is one of the first ones I ever shipped in a personal product. And I was happy with how little code it was. I do obviously a feature detection for service worker. And then this was basically our entirety of the service worker. It's just a simple like a pre-cache step. So obviously on our install, we grab that event. We have our array of URLs of files that we will definitely always have. And then we grab that event. We open up the cache that we have for it. And then once that resolves, we prefetch every single one of those with a simple request. We put it in our cache. And then we just also have a very simple fetch step where in case I add something to the domain later and I don't add it to the prefetch step, it's just automatically added there as well. We check to see if it's in the cache and if it is, we respond with it. And if it's not, we fire off another fetch. It's literally that's the entire content of our service worker just transpiled out of ES6. And it was great. We had all this super smooth working stuff. I was super excited because Holden got upset because he ran out of a bottle before he finished it because he eats a lot. And I picked up my phone and boom, and he stopped and I felt like super dead and I was so excited. I ran over. I showed Katrina. She was excited because no one likes a baby crying. You want him to feel better. And so she takes him into his room later and we're in an old building for America. I know I have a British friend to make fun of that but it's like a hundred years old, which is ancient for Seattle. And it's like thick brick walls and everything. And so in his bedroom, we have terrible cell phone reception. And so she's like, he starts crying as she's putting him into bed and pulls out her iPhone and then she goes to open up the phone, the app and gets this. And I'm like, crap. Once again, I felt like it just an absolutely terrible problem solver. This same problem happened just because I had made it work perfectly on my phone for my one solution. And so the problem is that it had no iOS support as we all know. There is no service worker support within iOS. And so I had to sit back and think about what to do. And a wise man once said when you don't have a better idea, try out AppCache. And yes, that AppCache, it's terrible. It's terrible. It's awful. I'm not suggesting that people actually super try it out. But what I am suggesting is that you don't immediately discount technology that you hear is terrible. There is a lot of stuff that browsers have been shipping for a very long time that might be able to meet your solutions. I work at Microsoft. I hear about old crap all the time. Stuff that we've been doing in IE 5 that is just now coming. Like Jake mentioned, the navigation transitions. There's all kinds of stuff that we did a long time ago that might still be useful occasionally. It's worth checking out. At the very least, it's worth knowing what we did wrong on these old specs like application cache. And in this case, what I was doing, oh, yeah, actually, it's so bad that it's being removed from HTML. I don't know how many things you know of that are actually actively removed from the HTML spec, but this is one of them. We all agree that this is terrible and needs to just be purged from our collective memory. But AppCache is incredibly well supported across the board. As long as you're not developing for like Opera Mini or God forbid, old IE, like you are pretty much guaranteed to have an AppCache support. And for a site that's as simple as the one I made, which is obviously much less complex than I'm sure most of the things you guys would ever make, it's really, really straightforward and actually fits all of our use cases. And so we just take our feature detect from before and we add another little feature detect. I don't know. A lot of people actually have never used application cache and so you might not be aware that in order to use it, it's actually an HTML attribute that exists on the HTML element and that has to be there at the very top of the page at load time. You can't dynamically inject it. Again, it's a horrible API. It's a giant douchebag. The attribute has to be there at crush time and so in order to get it onto the page, you have to bend over backwards and do it this way. And so inside of this check, what I end up doing is creating an iframe. I hide that iframe and then I give it the source attribute of like a specific page that only loads loading and AppCache. It basically just has that attribute. I'm going to add that at the bottom of the page. This is the entire contents of that HTML document. It's super, super small. It does almost nothing, but it gets that AppCache in there and it starts downloading all the assets. And so those assets that I have in my prefetch cache, I'm able to take that and through like a little webpack transform turned it into a web manifest or an AppCache thing out of there. And the cache manifest is a really simple file format. That's one of the reasons why it's terrible. It's because it's super like if you do this one thing, it makes sense and nothing else. So we have the cache manifest and then the files that we had before. And then we also have to have like this network star at the bottom. The reason for that being that AppCache automatically assumes that it knows everything and any URL that is not on this list will automatically 404. Even if you're online, it's a terrible API. It's really, really crappy. But if you know this edges and if you know what to do and how to get around those problems, it can be useful. Check out crappy APIs because there might be like a little glimmer of something useful inside of it. It is a douchebag. Don't forget that. But check it out. Don't immediately assume that just because you heard a technology, whether it's something built into the browser or a library or anything else is terrible, just because you heard it's terrible. Find out for yourself and learn. In fact, I was thinking about while I'm doing terrible ideas, I was remembering when I very first started in websites and we had this... Does anybody remember DHTML? Anybody ever had that on the resume? Yes, thank you. Yeah. Does anybody ever write in HTA? A hypertext application? Thank you, thank you, thank you. Yeah. So I made it into a hypertext application as well because why not? And so what I did was after all those checks, I shipped this as a... I checked to see if it's an old Microsoft thing. Oh, I'm sorry. HTA, or hypertext application, is a proprietary offline application shipped in Microsoft Internet Explorer 5. It's terrible. But... But it exists. And I figured I was already doing stupid shit anyway so why not have some fun? So if you go to this website, Hush Little Baby, in IE, you actually get this huge pop-up because there's no reason to be using old IE unless you're checking out the fact that I was stupid enough to add an HTA. And if you download it, you get this experience. You get this huge, nice little one-window pop-up. It has this little icon in the corner. That's basically the only fancy thing about it. It has a flash audio player because if we fall back from the web audio player, we load a flash player and so you have the full experience. Again, just because it's fun. But it's stupid. The whole point that I'm making is that PWAs, like Jake mentioned, are only been kind of a collective... the collective concept of a PWA is new. When Francis Bearman came up with it only a year ago, back in June of last year, but the tools behind it, the things, the fundamental pieces of PWAs have existed for a very, very long time. This offline application is not a new concept. There's a lot of pieces of the web and a lot of pieces of PWAs that aren't new concepts. They're just finally good versions of concepts that we've tried to do multiple times. And there's a lot of things that you can do today to kind of implement that. One of the things I hear regularly from people is that they're really excited about PWAs, but they can't ship them today because they can't wait to do a full re-site architecture. They can't wait to implement all these different features. And that's just not true. You don't have to wait to do this stuff. You can start implementing pieces today. For example... Sorry, yeah, I forgot my thought leader. It's not a radical new way to create websites. It can also be a radical new way to update websites. You can do stuff today on your website that already exists. For example, the Web App Manifest. In case you haven't ever seen it, it's a very simple spec. It's a very simple document. All it is is a JSON object that exists as a file on your page. You have stuff like your language attribute, the text direction, the name of your document, the description of stuff, so it can show up in application manager page, an array of icons so that you can just support a bunch of different devices. It's even stuff like orientation. You can finally lock your screen to landscape or you can do stuff like a theme color, so you could affect, say, the title bar on Android or maybe like the color of Cortana on Windows. We're looking into what we can do with that. You can even actually specify related applications. If for some reason your company thinks a native application is better, but they're still cool enough to do a PWA, you can say, if the user has this native application installed, fall back to it if they also have that. You can toggle that with the prefer related application flag. It's super, super simple to do this and the great thing about it is there's no JavaScript API to this concept. It's just an HTML tag that you inject into your page. You have that one JSON document, you add it to your page and you are on your way to having a PWA. You just inject it in there. And you might be noticing, actually, sorry, one of the cool things I wanted to actually talk about was that we are really, really excited about PWAs on edge and one thing that the Bing team is actually going to be doing is crawling the web to look for these sites that have web manifests. And when they do, we believe we're going to actually be ingesting them into the Windows Store automatically for you. And so you can easily opt out of this if you don't want to have it as a part of it. But what will happen is you automatically get interested into millions and millions of Windows users. You have this ability to reach out to them and once you're involved in our Windows Store automatically, just by shipping this web manifest, you can start doing feature detections for the Windows WinRT APIs. That basically should pretty much any Windows API that you have access to, you have full access to in JavaScript. We started doing this work in Windows 8 and it's available there. So you can do stuff like integrate with the system calendar just by doing a simple feature detection script and then checking to see if you're in Windows. And if it is, show the full calendar. You can integrate with Cortana. You can integrate with a lot of low-level things and have a truly native application feel in website code that you ship out automatically just by adding a manifest. It's a really cool thing to check out. And to make it even simpler, you know, so I was sitting and thinking about how frustratingly simple but also redundant a lot of this information was. You have that JSON object and a lot of that information that's on that JSON object is already in your application and all these meta tags that we've had to show into this tag soup at the top of our page for a long time now. And so I created this node application, sorry, a node plugin module thing called manifestation. It takes a URL and then gives a callback to you that just generates the most fully featured web manifest object it can create. And it really tries to be extremely full-featured. Like, for example, our language detection. It loads up the whole page using Cheerio, just like a server-side jQuery. And CLD, the compact language detection, which is a binary object. It's very similar to how Google Translate works. It can actually look at the context of words and how they're used until a difference between Portuguese and Spanish or something like that. And so we go ahead and load up the HTML of your page. We go and check for the language attribute. If that doesn't exist, we go and check for the XML language attribute because you might be making an HTA into a PWA for some reason. Then after that, check the DC language attribute, Dublin Core, if we have any librarians in the house. It's like a soup A. It's a really old meta tag that no one uses, but if it does exist, we want to use it in there. And then after that, we'll fall back to CLD where we'll actually look at every single word on your page, parses HTML, and try to automatically detect what the document is, just like you would do if you open up Chrome. It's foreign language. It's like, hey, do you want to translate this from Portuguese? It's exactly the same type of concept. And so after all that, we send back the string of what that language might be. That's just one of the detections that we do. There's for every single field on WebManifest, we have one. This is the beginning, the top, of like a 200-line file for images where we go and scrape every single image that's declared as an icon. You can download it, check the size, ensure that the MIME type is correct, ensure that the extension is correct, and do all this stuff, and generate the full icon array for you automatically. In fact, it's so easy to do this. I made a website so that all y'all can do it like literally right now. You can go to WebManifest. This website, it exists. It's this cool domain. It's super simple. Again, I love stupid domains. You just go there and you put in the URL, hit submit, and it will download your WebManifest file and it's like, all right, you don't have to do anything. You just download this, you add it as that link tag, and it works. It's great. And you're the beginning of having a PWA, and you can be ingested in the Bing Store soon. Yeah, you just get this pop-up download. You got it. It's awesome. So it's WebManifest. It's a super simple thing. If you want to end up changing what I do, because we try to be fully featured, you might want to remove some of that stuff if you think it's unnecessary. I added a short URL to the validator. You can just go there. If you want to make sure that you've modified and it'll tell you whether or not it's valid, if you have an invalid manifest file, it actually won't count as a manifest at all in Chrome or Android or anything else that's shipping it. So it won't work, basically. You would be blocked from doing a PWA. You want to make sure that you have a valid piece of JSON object. Also, the spec on this is really pretty simple. And so if you've ever been interested in doing W3C work, if you've ever been interested in getting more involved, this is a great one to dive into. It's a small group. We're all super friendly. We'd love to get more feedback on this stuff. If you want to be involved in, it's a great one to check out. It's a really fun thing to work on. And so while we're talking about stuff you can do today, you don't have to wait for all these new features to come. Jake just blew, I think, our collective minds with the stuff that's coming in the future. And there's a lot of really fun stuff, but there's also stuff that you can do for a long time on the web that is amazing. Take, for example, web workers. They actually landed in WebKit back in 2008. And 2008 in web years is just geologically incredible. The Chrome icon here is wrong. It actually was dead back in 2008. It is a really, really long time ago. And a lot of things have changed. IE8 wasn't even released yet. It was a long time ago. But since it's been around for so long, it's phenomenally supported. It's supported pretty much everywhere. It's back to IE10. It's really, really cool. And if you're not familiar with web workers, it's a really cool API. Has anybody here ever implemented a scroll handler? On scroll? Don't lie. We're among friends. Yeah, it's terrible. You instantly jank up your whole page. And that's because everything on a browser is completely single-threaded. Because the browser doesn't know are you going to modify everything in the DOM in that scroll handler so it can't relay out stuff until your scroll handler is finished because it would be wasting work. It sucks because most of the time you're probably not, and so what a web worker does is it gives us the concept of having a background thread. You're able to say, like, it gives you a new JavaScript context that has no access to the DOM that you send strings or possibly objects to depending on the version of web workers you're working with. And it's like, hey, go calculate this and then send back the results. And it can do that completely in the background. And so it can do some really hardcore, heavy number crunching without any way affecting your scroll performance. You can do a lot of really cool stuff with it. Take, for example, pokedex.org. I'm sure a lot of us saw this. It's Nolan Lawson, one of my amazing co-workers created this website as a really advanced PWA. It does an incredible performance on the site. And part of the things that makes it so fast is because it's like a React-ish powered thing. It's using virtual DOM. And it actually calculates the virtual DOM differences inside of a web worker and then sends back the diffs in between so it's able to render stuff faster. And the React team is actually investigating currently is doing virtual DOM diffing inside of a web worker. It uses, like I said, virtual DOM as this concept where it gets the diff, it sends it over to the UI thread where it applies all that stuff. And I don't know, this looks important. I'm concluded it because it looks sciency. But the cool thing is you have this phone. This is a Nexus S, which is a, I think, five or six-year-old phone. I should know this. I'm at a Google conference. I'm sorry. But you get incredible performance. It's like he just did this last year. And it's phenomenally fast. And look at how smooth that animation is. And one of the things that he credits as being able to do this so well is by doing his DOM diffing inside of a web worker. There's tons of crazy cool stuff you can do in web workers. Take, for example, Modernizer. Like I said, I'm the maintainer. We have our website, our dynamic builder is completely client-side. I built in a whole lot of stupid stuff into it like I showed you the HTA right now. And all these different things that you can do to build a modernizer that you don't need to know about. And it goes off. It'll go ahead and download the entire module. They're all modular pieces, right? And one of the problems we had on the Modernizer team is that people were including the entire build of Modernizer. And as we grow to more than almost 300 modules, that can be a gigantic piece of JavaScript. And frankly, most of you don't need to know whether or not border radius is supported in the browser, right? There's all these tests and all this code that actually have a GZIP calculator up in the corner. And so as you check stuff off, it updates. And we do that full GZIP comparison inside of a web worker in the browser without ever going to the server. We're able to do that because a web... And we're able to do that every single time you click off stuff because web workers are so cool. In no way does it affect your scrolling, your performance, the animations, or anything else. It's just a really silky, smooth, fast experience. And you're able to get some really neat information. In fact, I love web workers. I can so much so that I'm looking into a new project right now that I've been working on where it has a terrible name if anybody has a better idea. I call it web worker preprocessors. So we've all used transpilers. We've all used stuff like Hamel or Jade or other stuff like that. I love them. I want to take them and run them on this client side. I love sites like JSbin or CodePen, but I want them to be a PWA. I want to be able to run that offline. And so what this is doing is actually a toolchain that automatically creates cross-compiled version. It transpiles transpilers to run inside of web workers. I have a number of ones already working, including some Ruby-based ones. We have stuff like... What do we have? We have less support, slim support, Pug, Jade, the old version of Pug. We have Autoprefixer and even Hamel. And I'm currently working on SAS. And they work. The Ruby stuff is actually transpiled using a cool project called Opal, which takes Ruby code and transpiles it into JavaScript. And they work. They have a single version of Slim, a similar to Hamel Ruby version, throughout its get range, like literally 58 versions of it, running inside of a web worker, passing their own full test suite. And it works. And it works really well. If you're interested, I'd love to talk about it, because this is what I've been doing at night. It's a lot of fun. But the point is, web workers are cool. You can do a lot of crazy cool stuff, like cross-compile Ruby into JavaScript in order to compile your templates. I'm talking about. And the whole point of what I'm saying with all this nonsense and stupid ideas is that when you build stuff, try out something stupid. There's a lot. We can do all kinds of really crazy cool stuff on the web. And you shouldn't be thinking that you have to wait for it to be supported everywhere to do something stupid. Try something cool today in one browser. If a feature is supported in one place, be it Safari, be it Edge, be it Chrome, be it Firefox, try it out. If you're interested in a feature, try to ship a feature. The way that browsers actually decide on whether or not to support a feature are based on what y'all do. If everyone started using web components back when they first were introduced, then everybody would be supported on web components. It's this weird prisoner dilemma where people think that they have to wait for browsers, but browsers wait for the people. Start using stuff that interests you. Give the developers feedback. Give the spec authors feedback. And then you can start shipping for a rearchitecture in order to start shipping a PWA. You can start shipping individual pieces like the web manifest, like a really simple caching service worker today. You can do it today, literally right now. Almost every single site that can implement that stupid 18-line service worker that I had in a way, and you will instantly... Your whole site might not work offline, but you can have faster caching. You can have a faster load from almost all your users. Try out the new sign-in features and try it out today. The web is really cool. Thanks, everybody.