[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]
Incorporating redux into the starter kit was a smart move
Kwl
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.