PWA starter kit: build fast, scalable, modern apps with Web Components (Google I/O '18)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Incorporating redux into the starter kit was a smart move

👍︎︎ 3 👤︎︎ u/iamlage89 📅︎︎ May 31 2018 🗫︎ replies

Kwl

👍︎︎ 1 👤︎︎ u/MrCartmenes 📅︎︎ May 31 2018 🗫︎ replies

Man this has been a beast converting a polymer2 app to polymer3. All the best polymer2 components have bugs and need to be updated but seems that little is happening.

👍︎︎ 1 👤︎︎ u/fiddel_fabulous 📅︎︎ May 31 2018 🗫︎ replies
Captions
[MUSIC PLAYING] MONICA DINCULESCU: Hi, everyone. I'm Monica. I'm notwaldorf on Twitter, GitHub, internet places. And I work on the Polymer team. And if you've ever heard about Polymer or the Polymer team, we're always excited about the web. We're excited about DOM APIs. So I'm here to tell you that-- I don't know if you've heard this-- but the web is pretty great. It's portable, it's fast, it's in everybody's pockets all the time. You get to write apps that you write them in HTML, and CSS, and JavaScript, and they work on all sorts of weird devices. And these are called PWAs. They're Progressive Web Apps. They are shiny. They work offline. They feel like native apps, even though they're not actually native apps. They just work on the web. And this year is a really exciting year for a PWAs because they're on 4 out of 4.5-- it's actually 6 out of 6.5 browsers. They work on Chrome, and Safari, and Firefox, and Edge, and Opera, and Samsung Internet. And they sort of work on IE 11, because they degrade gracefully. But you know, not everything works on IE 11, so we're not going to hold that against them. They also work in app stores. Microsoft recently announced that along with native Windows apps, you can find PWAs in the store. And then you can install them. And they have, again, this like nativey feel to them. They are on desktops. Chrome announced that you can install a PWA just like you do on Android on your native desktop machine. And you can have the little shortcut. And you can double-click the shortcut. And it opens, and it feels like an installed app, even though it's not. It's a web app. It's been a web app all along. Progressive web apps are everywhere. So if you're going to build something soon, you might think, you know what? I should build a PWA. I get to write it once. It works everywhere. But oftentimes, when you start building something, especially a new project on the web, it often feels like this, where that poor soul in the middle is you, and all the Tupperware falling on you is all of the things you have to implement. You have to have a framework to render your elements. They have to be accessible. It has to work offline, and on mobile, and on IE 11. And it has to be shiny. And oh, my god, there are so many things. And it feels awful. And it kind of feels, you know, not great. And that's because if you think about this graph of effort versus results, you have to do a lot of effort to get to a point where you can even call it an app. And it's kind of soul crushing because it sucks to work hard and not really accomplish a lot. And where we want you to be on this graph is isn't here. It's all the way at the beginning. We want you to do very little effort and get awesome results off the bat. Because then, the hard stuff you're working on is your hard stuff. It's not just like boring boilerplate you have to implement just to call it an app. And the way you can get this done is by using a kit. You have to reuse somebody else's components and elements in just a regular kit. Everybody on my team has a saying. Steve says, do less, be lazy. Kevin says, hard things are hard. And I've started saying always be componentizing, because that's how things really work. Using a components is the only way to do things scalably. And I mean this in the real world. When you buy an Ikea table, you have different components you put together. You have a slab of wood. You have some legs. You have some screws. You don't go into the forest to shave down a tree to assemble that plank of wood. You don't go to the mine, mine some ore to make tables. You pick somebody else's components, and you put them together, and that's how you can get a table done in like an hour versus like a year and a half. And that's optimistic because I don't know if you've been playing things like games where you have to mine ore. It takes forever. In an app, you do this exact same thing. You pick other people's elements. You pick a router. You pick localforage if you want async local storage. You don't rewrite each of these modules and libraries every time you need them in your application. That's banana pants. On the view layer, you have the same thing. You use web components. Web components are encapsulated UI widgets that you can pick and choose. And they have their styles inside. And you get to use them in everywhere, and it's super easy. And web components-- if you saw the Polymer talk earlier-- they're first class citizens of the web now. Everywhere you can use an input, you can use somebody's web component. And that's really awesome and powerful. These are the web components that you could use. You could use somebody's bar-chart and date-picker. You can stop reinventing your date-picker in every single application. Great news, everyone. And I'm very happy to tell you, we have this kit. PWA starter kit is a thing that the Polymer team has been working on. And you can find it there. And it's basically a template that lets you build PWAs. It has all of these components pre-chosen for you. And then you can mix and match them to make your PWA. And we're announcing it today. We shipped to version 0.8, actually 0.2, this morning, because we want you to demo it, and play with it, and give us feedback before we go 1.0, and we can't take back any of the features. So what would be-- how would we use PWA starter kit to build a PWA? And in order to not bore you with words for the entire time, I built a game. (SINGING) Do, do, do, do, do, do. Super PWA Adventure-- the awesome one-player game to build PWAs. For any lawyers in the audience, this game and the characters depicted are fictitious, and any similarity to actual games, living or dead, is purely coincidental and definitely not because I've been playing hundreds and hundreds of hours of "Breath of the Wild." So every good game has a map. We are that little lady with a wrench. Because I built the game, I have the wrench. And we're going to build a PWA, which lives in that castle. This is the first game where the princess doesn't live in the castle, your users do. That's where your users belong. So every good game has levels. Our first level is the tutorial. It's where you figure out how to get by in the game. We get our armor. We figure out what kind of baddies we're going to get. And then you get some building blocks. You figure out what are the basics of the game. It's like the easy puzzles just to get introduced to the game. Then you figure out the slightly harder games and patterns that you need in the game. So things like in "Zelda," you need to chop all the grass to get rupees and stuff like that. And then eventually, you realize that not all puzzles are the same, so you have to figure out extra combo moves to get through the super hard levels. And finally, the boss level is where we actually have to ship and deploy this app and give it to our users. And if everything goes well, and we have killed the final boss, we get fame, and money dollars, and awesome, and we go on a vacation to the Bahamas. And that's where we want to be. So let's play PWA Adventures. Every good game starts with armor, like your basic set of armor and your shield and your weapons. And our shield and weapon in this game is the PWA starter kit. We start with it. And then, we figure out how to use it. So are you ready for the first level? That's right. (SINGING) Do, do, do, do, do, do, do. Pew, pew, pew. We have to get started in seconds. Nobody likes tutorials that last forever in the games, and you can't skip them, and you have to go through them. And you're like, oh my god, I already know how to run-- just let me run, just let me run. So the goal of PWA starter kit is to let you get started in seconds, without having to mess around for too long. So if you go to the wiki, the first thing that you see is the things that PWA gives you, and then how to get set up. And then once you do that, you can go into the advanced levels. So the way you get set up is you clone the repo. You run npm install to get its dependencies. You run npm start to make it go and to see it locally. If that worked out well, you can run npm test to see how we do testing and to see that it's actually passing all its tests. And then, you can run npm run build and npm run serve, so that you can minify your build and build it for production, and then actually test this production build. So when you actually start your application, this is what it looks like. It's a very small application that has three pages. One of them is a static template, and the other two are small examples that use a bunch of data and state management so that you can get inspired if your application actually needs them. One of the examples is a full-blown shopping cart where you can buy my favorite cheeses from San Francisco. Cheese is the best. And then, of course, it has a responsive layout because all apps need to work on mobile and on desktop. And a template that wouldn't have that wouldn't make any sense. So that's already built into the application. Cool. (SINGING) Do, do, do, do. Boo, boo, boo. We got started. That was the tutorial. It went super well. And now we're kind of confident that this PWA starter kit is actually going to be a good weapon and armor for our game because it didn't take forever. What's next? Next are the building blocks. (SINGING) Do, do, do, do, do. Pew, pew, pew. Fun fact about noises-- Jake Archibald tried to use noises from a video game once. And you're not allowed to because you're not licensed to use them, so he had to make, I think, "Street Fighter" noises by mouth. So mouth sounds get you everywhere. So the thing that we deploy-- the thing that we were testing-- isn't the PWA that we want. Not everybody is going to have that lorem ipsum app. That's not the app you're trying to build. So the next level that we have to beat is figuring out the building blocks of this application so that we can add our views and our elements, not the ones that the template comes with. And this is our first real level. If you think about a view, it looks like this. It has components, and elements, and all this stuff in it. And all of these components and elements are separated because we're using web components. We believe they're good for our apps. And these components need to be lightweight, and fast, and expressive. They have to be lightweight because if one element is super heavy, that entire page is super heavy. And it doesn't matter what you're optimizing in your app. All of your JavaScript bandwidth is going to that element. They have to be fast because if your elements aren't very fast, you're going to take forever to render and nobody is going to want to hang out on your page. And they have to be expressive. Whatever you use to build these elements has to let you build any view in any element that you want, because otherwise, it's not going to be really fun to use. So in order to build these elements, we picked a new base class called lit-element. And this is a very small new base class that lets you do basically everything. And it's super small and fast. And it takes advantage of all of the new features that have arrived in browsers recently. It lives over there. You can also npm install it from @polymer/lit-element. And it's built on top of lit-html. And lit-html is a very small library-- it's like 2K or 3K in total-- that lets you write HTML templates as JavaScript template literals. So this means that you can just use all of the magic that JavaScript lets you do inside of template literals to express any dynamic content your element might want. And it does so really, really, really fast because it knows exactly what you need to render, and it only reupdates it when you need to. So it does it this way. First, a lit-element reacts to changes. So every element has a set of properties. And these are things that the element cares to render and cares about. And these are just like a value, a click, something like that. And whenever any of these properties changes, the render function is called. And in this render function is the template that your element looks like. So two things might happen when you look at this code. First of all, you're like render? I've seen that in React. What is going on? And true. So this has a same reactive model that you've seen in React. And you're familiar with it, so you don't have some sort of library weird jank when you do this. And the reason why this model is really good is because it's a very simple way to think about what your state is and what your element looks like. You can write everything declaratively. You don't have to write weird listeners on buttons or anything like that imperatively. You can just do everything declaratively here. So what kind of things can we do on this render function? Well, you can obviously have static content. But you can also have dynamic content. If you have a property called myMessage, you can put it and display it in here. But all of this is just a JavaScript template literal, which means I can write advanced expressions in here. So I can conditionally render different things. Of course, I can also have buttons that have inline event listeners. And all of this just works. And the really important thing here is that all of these things only update when their lit bit updates. So if my message updates over here, only that div gets rerendered. Everything else stays the same around it, because that's the whole power of lit-html. It's magical. And when you make it into an element, it looks like this. You import it from a module. We know this. These are ES modules. They're not new. We have a class. It extends the base element. We register it at the bottom. We define it with a tag. And then we do our properties, and render, and everything else in there. And this is it. This is the whole base of lit-element. And it works really nicely. You can also, of course, have encapsulated styles in them. One of the awesome properties of web components is that you can encapsulate CSS inside of them. And we do this by letting you export a style from an ES module, and then importing it, and then just using the squiggles to import it inside of your element. And this is native shadow DOM. This isn't CSS in JS or weird things that need transformations. This is what shadow DOM looks like and natively, and awesomely. So we have our view. But just making static elements in a view isn't how you build an app. You need to glue them together and then put all these sorts of logic that responds to route changes and stuff like that. And when my team was building apps-- because that's what my team does, we build apps-- we noticed that all of us were writing sort of the same boilerplate code over and over, and over again, to glue these views together. And that was also kind of soul crushing. Because any time three people have to write the same thing and they're like, oh, my god, I'm doing this again, that's not a good place to be in. So we created a helper for that. And it's called PWA helpers. And it's a whole bunch of tiny little snippets and helpers that you can add to your app. They have no dependencies. They're just small snippets of JavaScript. And you can add them anywhere. They're kind of like croutons-- delicious things you can sprinkle in your soup and salad to make it better. They live on GitHub, also on NPM. You can npm install them-- pwa-helpers. And we're going to use them to glue these views together. So what kind of things are in PWA helpers? There is a very simple router that you can install in a one line. You install it, and it gives you callback any time the location changes with a new location. And that's all the things you have to do. There is a network listener that basically gives you a callback, again, when you go from online to offline, so that you can conditionally render your offline UI only when you need it. And there's a whole bunch of one-liners like this, that you only install with one line. There's something that lets you observe media queries in JavaScript, updates your Twitter cards and Open Graph metadata, lets you connect to Redux-- and I'll talk about that one in a second. They're just little tiny helpers, just there to make your apps better. (SINGING) Do, do, do, do, do. Pew, pew, pew. We've assembled our app. This is awesome. So now, we understand how PWA starter kit works. We have these views. We have these elements. They're glued together with lit-element and PWA helpers. And now, we're ready to add our own views. So we're off to the races. Now, the next level is figuring out patterns. (SINGING) Do, do, do, do, do, do. Pew, pew, pew. And this is the time we're like, things get a little bit hard. We have to level up. Because in every game, there is a point where you have to learn a specific pattern. In "Mario," you figure out that you have to take those shells and throw them at everybody and that's how you win. In "Zelda," you figure out, again, with the rupees. But also, you figure out that any time you see a crate, you have to bomb it because there is definitely something in there. Also a wall that has cracks, always bomb it. And in Super PWA Adventures, we learn about patterns that we can use because patterns save you time. Games would suck horribly if every single level was completely different than any other level, and you had to relearn the entire world every single episode. That's not how we play games. And clear patterns help our new team members figure out an application quickly, because they've seen those kind of codes and patterns before. That base-- the base view class that we have-- lit-element-- it's present in every single web component that's used in PWA starter kit, which means you can look at every one and be like, oh, I know this. I've seen it before. It looks like all the other ones. And using a pattern is scalable. Because as your application grows, the goal of patterns is to make sure that your code isn't a mess, your structure is there, everything's well-documented. There's even patterns that ensure that your application is super performance, and everything stays awesome, even though you have now 530 pages and everybody's just like adding new views because they can. And there's two patterns I want to talk about. The first deals with application state, and the second one deals with performance. So for application state, we looked around the community for the best way to do this. And we're like, should we reinvent the wheel? Obviously not. And the best solution that we found is Redux. And we're super happy about this because Redux has an awesome developer community, which means that every time you have a problem, there's probably a solution for it there and we don't have to find it. And the point of a kit is that it's flexible and lets you plug-in all of your solutions. So if you don't like Redux, you can just take it out and plug-in your own application state solution in it. But just in case you want ours, and you don't know what Redux is, Redux is a small state container. It basically is a glorified key value pair. And that's how it stores your data. And it's very tiny. It's 2k, so it doesn't really add anything to the size of your application. In particular, Redux is view agnostic, which means it works the same in any application that you use. You can use it in a React app, in a Vue app. It doesn't matter what your elements in your view layer are done in. Redux works the same way behind the scenes. And this makes it really widely used, because it's really reassuring that all of us building applications and all of the frameworks out there have the same problems all the time. So the solutions for them are often really clear and well-documented. And in particular, Redux lets you time travel. And if you don't want to pick whatever tool lets you time travel on principle, then I don't think we can ever be friends. And by time travel, I mean this debugging technique, where you can have your application and you can install a developer too. This is the one we use. It's documented on the wiki. And basically, as you're navigating and interacting with your app, it records all of the actions and all of the states at the different points in the world that you're taking, which means you can also rewind time. If you find a problem in your app, you can rewind time to right before it happened and check what the state was and what happened to it. And this is really awesome because it means that whenever you have bugs, you don't know have to restart the dev server, do all the clicks. Oh, no, I've done the wrong click. Hold on. Restart the dev server, do all the clicks, hope you do them correctly, and so on. Time travel is amazing for debugging. The premise of Redux is actually very simple. You have your UI, and any data that needs to flow through that UI lives in a store. And that store is the guardian of that state, and nobody else can touch it. This means that if the UI needs bits of that state, it can ask for them. But what it gets is an immutable object. If you touch it, it doesn't matter. That's not the data that actually lives in the store. You just get the immutable version of it. And of course, if the UI needs to update it, it can send an action to the store and be like, hey, buddy, I need to change this clicker count value to add 1 to it. And the store goes, sweet, I've done it. But if you just had this, you would have a lot of code in the store. And what do I say? ABC-- Always Be Componentizing. So Redux has this idea of reducers, which are smaller functions that update the data for you and then put it in the store. And these functions look like this. They all deal with a small chunk of the data. And they take the previous value or do something to it and return the next value. This is a counter that updates a value, whether it gets an increment or decrement action. That's all it does. You can have many different reducers across your application depending on what kind of data you have. So those are reducers. And then, the UI needs to talk to the reducers somehow, so it dispatches actions to it. And this is what I pretend it looks like. This is not what Redux says it looks like. But if you think about your UI and your reducers, the actions that you take on the view layer aren't necessarily the same actions that happen in those stores. So if you think about-- I don't know-- logging out of an application, you're going to press a button that says log out. So the UI only knows one action, which is log out. But what happens behind the scenes is actually complicated. You've got to set some cookies, talk to some servers, change the UI, do all these things. So the dispatch function is there to convert your UI actions into what I call data actions. I don't know. I call them. Now, the top part of the top is Redux classic. There's nothing that we've invented here. This is like Redux straight out of the box. You can go to the Redux site and read everything about it. The bottom part is the one that's interesting to us, because how you connect Redux to web components it's kind of interesting and not a lot of people have been doing it. So let's talk about that one. You have your element that we've had before. We've seen this. This is a lit-element. And we connect it with that mixin. So this is another one of those little helpers that we added in PWA helpers. And it basically, when the element attaches, it subscribes to the store. When the element detaches, it unsubscribes from the store. And every time the store changes, you get this callback called state change. You could, again, write all of this by hand, but why write it yourself when you don't have to. You can just use a helper. And what happens in that state change is that you update your properties. And again, this is a pattern we've seen before. This is the glorious benefit of patterns. Our element has a property, so every time the state change, we take that value and we put in our property. And of course, every time we update a property, render gets called, so we're going to rerender the value of this property. This is pretty cool. It works pretty well. But of course, I need to update the value in the store somehow because that's the whole point of something that I click. So we do that with actions. Again, whenever you click a button, it dispatches an action, and then it goes into the store, and the store updates it, and then I get state changed again, and the value comes in. And this is where lit-html and lit-element are really powerful again. When the value updates, only that little div is going to update. So we're now worried that if we get too many updates to the store or we update this value to often, it's going to be too slow, because everything else doesn't need to be affected by this rerendering. Woo. So that's Redux. It's pretty great. And it scales up really well to really big applications. And a lot of people are using it in their applications. So the next one is performance. And for performance, we use a pattern called PRPL. And PRPL stands for Pushing your critical resources for the initial route, Rendering that a route, Pre-caching the remaining routes, Lazy-loading everything, and then creating it on demand if needed. PRPL. It looks like this in practice. The happy thing is you, your browser. And you're requesting a view from a server. And the server looks like a stack of pancakes because if anybody has a better icon for a server I will take it. Pancakes are delicious, but I don't think that's what a server looks like. So the stack of pancakes is going to give you back, oh, it's should say view1. So it's going to give you back the view, but also going to figure out that you need other resources. So you didn't update the slide in time. So it's going to push to you other resources that it knows it might need. And it does this based on the http2-push-manifest. So it's going to look and be like, oh, you need this view, but I also know that you're going to ask for these other two JavaScript files. And it's going to give them to you so then you don't have to do a round trip to the pancake stack when you need them. So now the browser is super happy. It's going to render that view, and at the same time, install a service worker. And the service worker is going to cache all of the views that you might need later, just in case you do, so that when you do actually request one of these views, they're already locally in the service worker. You don't have to go back to the stack of pancakes, which is always really slow and takes forever because you need to get the Nutella and the maple syrup and all that stuff. So it gets to render them. And then in your code, you get to lazy load that code because you've never loaded this view before. Don't do things unless your user asks for them. Always lazy load everything. Always lazy load it from a cache. That's even better. In your code, that looks like a dynamic import. Dynamic imports is how we dynamically import VS modules. So this is the action creator for a view. And for a view, it's what the router calls back. And then it's going to be like, oh, you need this new piece of code. Here, I'm going to dynamically import it. And because these modules are loaded magically, if you've ever imported this file before, it's just going to get it from your local module cache. That's awesome. But then, view might also have reducers in it because it might touch a piece of data that you haven't seen before. So we've added a way to also load these reducers lazily. And this isn't Redux standard. This comes from one of the helpers that we added to PWA helpers. So you can add magic to your Redux store, so that you can always lazily add reducers. And thus, the PRPL pattern is complete. So that's how we deal with application state and performance. And the best part about both of these patterns is that if they work for two views, they work for all of your 530 views, because you just reapply the same pattern over and over again. And all of your views are lazy loaded, so it doesn't really matter how many you have. These are only two of the patterns that we have in PWA starter kit. There's more of them. And you can also add more patterns, and plug and play them as your application needs them and scales up. (SINGING) Do, do, do, do, do. We saved time by using patterns. I don't know what my winning sound is. I was thinking about it, but I don't think I'm allowed to play the "Zelda" one, so. We saved time by using patterns. We now figured out that every time we have a problem, we have a solution for most of them. So that's awesome. Woo. We're so close to getting to the castle. (SINGING) Do, do, do, do, do, do. Pew, pew, pew. The next part is learning the combo moves. In most games, you have mini bosses, you have puzzles that are just a little bit harder. In the old "Zelda" games, you had the water temple that was just like all of the things that you'd seen before combined together and harder and with new things. And the same thing happens when you build an app. So the things that we know from PWA starter kit that we can solve already are there we have a base class-- lit-element. We have a responsive UI because our template comes with these app elements that build a responsive UI for you. We have the PWA helpers that glue all of the things together and make our application easier to use. We have Redux and PRPL, which are great patterns that we can use whenever we have problems. But we're going to figure out eventually that not all apps are the same. At some point, you're going to have a problem that the PWA starter kit template is not going to solve. I promise you this one. So it's important for a kit to give you the flexibility to deviate from these decisions, because even though we're comfortable with our decisions, you might not necessarily agree with them. So we have other templates that you can start with-- templates like the Redux one is the one you've seen, but there's also a template that looks identical and has the same amount of classes and everything, but doesn't use Redux. It just uses unidirectional data flow, because maybe that's the thing you've learned and you're comfortable with. We also have a template that looks slightly different. Rather than converting the lings from a line to a response UI. We have a persistent drawer that stays there on the screen when your screen is white. We also have a template that has no fancy UI whatsoever because it's very likely you already have a design system or an idea for what your UI looks like, and it's probably not pink underlines because that's my idea of a UI. So you can start from that one. And all of these different templates are documented in the wiki, and they're in great detail. And you can figure out which ones you want and you can pick and choose from them. There's also an advanced page where you can have more advanced topics. So rather than putting code into the wiki, we have just like putting code into the template. We have code into the wiki that you can pick and choose-- things like what do I do about SEO, and how do I theme my application, and stuff like that. But that's still not enough, because there's fairly advanced use cases that you might want. So our team has been building applications with PWA starter kit. And we built three new ones. And the reason why we built these applications is that we could have added all of these features to PWA starter, but it would have been horrifyingly full of features. I recently started playing "Skyrim." And in "Skyrim," you have a weight. You can't just horde all of the kettles that you see in everybody's houses. At some point, it's going to be too heavy and our hero can't move. The same thing is with code. You just can't put every single thing that you think of in one application and hope it's going to be readable to everybody else. Shop is an application you may have seen before. It's your standard e-commerce site, where you can buy things, add them to a cart, check out from that card, give me your credit card. I'm going to do some crypto mining. It's going to be really cool. But we have three more new apps. And Frankie, and Keanu, and me-- and this is the PWA starter kit team-- have been building them. We have an app that lets you read Hacker News. It's just a Hacker News clone. We have an app that lets you search the Google Books API. And we have an app that tries to teach Japanese using flashcards, or any language that you want. And the way we think of these apps are just like armors-- shelves of armor-- that you can pick and choose features from. If you've played "Zelda, Breath of the Wild," you have layers and layers of armor, and you pick the ones that you want. When you have to swim up the waterfalls, you pick the ones that you got from the water land. But you don't use them for running around, because they're not really badass. They're just good for swimming. And that's exactly what the apps are. You pick the one feature that you want and you add it to your application. The flash cards app teaches you about theming. It looks completely different than all the other apps. It has speech synthesis because it reads out the questions to you. And it uses local storage to save your local state. And that's because its a game. You have to pick off-- you have to start from where you left off every time you refresh it. The books app teaches you about authentication using the Google Sign-in API. It also uses speech recognition because you can just read the words out loud into the books app. It also has fancy [INAUDIBLE] UI. And these are the cards that you may have seen on Twitter, or on Facebook, where we pretend the content is there so that it gives you an indicator of what the layout might look like. The Hacker News app teaches you about fetching data from a third party API, getting a giant piece of JSON and sort of rendering it to the screen without waiting for 17 hours. It has favorites, so that it can save things and read them later. And it uses Indexed DB to save them. So if any of the features are-- if these are any of the features that you need, you can look at these apps and they're going to feel right at home because they all use PWA starter kit. And if you're familiar with PWA starter kit, they have the same structure and they have the same naming scheme, and the same patterns across all of the apps. And they're all documented here. And there's links to all of the repos and all of their demos. They're all open sourced on the wiki. And you can use them whenever you need to. (SINGING) Do, do, do, do, do, do. Pew, pew, pew. We got a power up. We're now leveled up. Look how many stars we have. We're in a "Zelda" game. We're doing super well. We're full of hearts. The only thing that's left is the final level. (SINGING) Do, do, do. Pew, pew, pew. We have to actually give our app to people. It's really great that you've built an awesome app that runs locally, but it's our final level. We've got to give it to users. And we started with a template. That was our first level. We customized it. We understood how it worked. We use advanced things like Redux and PRPL, and we added machine learning because everybody adds machine learning to all of their things now. But we've got to ship it. And that is our final level. We've got to defeat the final boss. And that is deploying-- putting it on a server and giving that link to people. And in order for you to do this, you need confidence. And you need confidence the first time you deploy it, but you also need confidence every time you're redeploy it over and over again. Because if my app works today and I do an update it doesn't work again, I promise you, your users are going to be pretty horrified. And testing is the only thing that can give you the confidence that every one of your redeploys is going to be successful. And testing is kind of like the shield to protect you from the monsters in your game. And the monsters are the rage of your users when you broke their calendars. And for this, we use testing. And testing is another pattern. We have a structure. We've provided some starting ways to test, so you know exactly where to put your test. You don't have to think about it yourself. You don't have to invent a setup yourself. So we have unit tests and integration tests. And they both serve very different purposes. Unit tests make sure that functional elements in your application stay correct between commits. A button is clickable and brings out this dialogue all the time on all of the browsers. Integration tests on the other hand, sort of make sure that from the beginning to the end, your application looks the same as it used to be. You don't necessarily click all the buttons, it just is a double sanity check that everything sort of looks OK. For unit testing, we use Mocha and WCT. And we run it on all sorts of browsers. And you can run it locally. And you can run it on Travis. But in particular, what's kind of awesome is that we've added accessibility testing to unit testing. And we do this via axe-core. Axe-core is an awesome library written by the Deque labs team. So we have a wrapper that basically is one function, where you pass it a DOM element. And that wrapper is going to spit out all of the violations-- the accessibility violations-- that that element has. And this element can be like a button or it can be an entire view that you're testing all at once. In this case, I have a button that doesn't have a title. And I get all of its violations. And this is really awesome because accessibility is a feature you don't really want to break. For integration testing, we use Puppeteer, which is a headless Chrome browser. And Eric Bidelman is going to be talking later about this on stage two. But Puppeteer basically lets you spin up a headless version of Chrome, and look at a site, and take screenshots of this site, which means we use it for screenshot testing. We look at what all of the pages look like. And we compare them to what we think the pages should look like correctly. And if they do, you're A-OK. And because these are tests, of course, they run on Travis, which is a hosted continuous integration server. You can use CircleCI or whatever you want for that. But you can just add your tests to continuous integration, so that you're always confident that none of your commits broke your application. So now that this part was easy and we're confident, and we're all armored up to fight the boss, we have to actually do the fighting. We have to actually deploy it. Well, PWA starter kit took care of this too. We have npm run build, which builds and minifies and makes the bundles for your application. And then you have npm run serve, which lets you test those bundles locally, so that you're confident before you copy-paste them to your server. And npm run build, even though it looks really simple, it does a lot of things behind the scenes. It minifies. It generates the bundles. It builds a service worker so that you can pre-cache all of those routes that I promised you about. And then there's two kinds of builds you can generate. You can build static builds, so that you can upload them to things like Firebase Hosting or Netlify. Or you can build dynamic builds with PRPL Server. And PRPL Server is this awesome thing. It's a production-optimized server. It's a little tiny node server that you can install on your hosting if you have access to it. And it does this awesome thing where it serves the optimal bundles to the browsers that request them. So that means that you can have multiple bundles. This is the bundle for IE 11. This is the bundle for browsers that have dynamic imports. This is the bundle for things like Firefox that still need web components polyfills and stuff like that. And PRPL Server will look at the browser that the request is coming from and be like, oh, I see. These are the things you need. Here's the bundle that works for you. And the reason why this is really awesome is that it means that you don't have to deploy an ES5 build, for example, and serve it to Chrome, which already knows how to use ES6, and fat arrows, and all that stuff. You can just give the correct bundle to every browser as they need it. And this is really awesome and powerful, and improves your performance. And once you do this-- once you run npm run build and then you test your build-- you'll notice that you have amazing Lighthouse scores because all of the heavy lifting and all of the heavy performance work was already taken care of by the PWA starter kit patterns. There was really good armor so the deploying monster didn't really attack you. And you can improve that 97 to 100 by just adding more lazy loading. But again, if you put it into a template, then it's going to be a little too heavy for everyday use. And that's awesome. We've beat our final boss. (SINGING) Do, do, do, do, do. Pew, pew, pew. Whee. We've deployed our app. This was our whole goal-- to start with a kit, and in 28 minutes and 12 seconds, we've managed to deploy an entire app from start to finish-- 38 minutes. That's it. We have finished our thing. We can go to the final castle where we're showered with money, and cake, and candy, and sugar. This has been my game. I hope you liked it. I hope you try PWA starter kit, and most importantly, you tell us when you build something with it because we'd love to hear about it. Tweet at us at @notwaldorf is me. @polymer is my team. And thank you so much for watching this. [MUSIC PLAYING]
Info
Channel: Google Chrome Developers
Views: 147,006
Rating: undefined out of 5
Keywords: type: Conference Talk (Full production);, pr_pr: Google I/O, purpose: Educate
Id: we3lLo-UFtk
Channel Id: undefined
Length: 37min 47sec (2267 seconds)
Published: Wed May 09 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.