I want to talk to you today
not just about the problems
that we've got necessarily with
regards to how web apps have
in the past been boxed into
one location or another,
because-- do we have slides for?
Apologies.
Do we have slides?
Or the other slides?
We'll come back to my debugging
session in just a moment.
I've done this all
wrong, you see.
All right.
Oh I see.
I was on the wrong screen.
It was nice to see my co-workers
actually watching and editing
my presentation in real time.
That's going to make
some good times here.
And go.
All right.
Wow, that's not focused
in the right window.
Yes.
Hey, there we go.
So I'm going to
talk to you today
about making web
apps appy or appy
web apps or something
along those lines.
It's a really difficult kind of
a set of words to pack together
because there are expectations
about what an application are
are kind of different to
our expectations of the web.
We expect that the
web is going to get
us the most reach possible.
You'll see the new device
lab out here today,
which I know that Chris
Wilson and other folks
here have been putting
together furiously.
But the best thing
about the device lab
is that it shows you in one
concrete place the enormous
of reach the web.
Not only have we been able
to create a platform that
gets you all the users from
one producer's device or one
set of manufacturer's devices
or one operating system,
we created a platform
that gives you access
to pretty much
every device that's
been shipped in the
world in the last decade.
We have more users on Chrome--
I was looking at the numbers.
We have more users on Chrome
than all iOS device shipments
to date.
That's not to say people
using iOS devices.
That's all an iOS
devices ever made.
Think about that for
a moment, and then
think about how you invest in
those two platforms differently
and your expectations of them.
And they're very
different because the web,
despite having enormous reach,
is a little bit awkward.
And that awkwardness is a big
issue not necessarily so much
on the desktop when
getting to the stuff that's
just there is really easy.
It's up hanging in a tree.
But in the mobile web, we've
had a bit of a disconnect
because the power that
you get between being
able to deploy your
application to pretty
much every user everywhere
and the ability for them
to frictionally share
it with everybody
else, and the ability for
those experiences to show up
in indexes and crawls and make
it possible for third parties
to also help share the
experience that you've
built with other people for
whom it might be relevant--
that power doesn't really work
well with the UI surface areas
that we're all carrying
around in our pockets.
Access to the home screen, being
able to be in the notification
tray-- all of those
things are critical when
typing something on a little
tiny screen with a-- even
with the better
keywords we've got now,
lets it let's admit that's not
sort of where we want to be.
Someday we'll be able
to talk to our phones,
and it'll always just work, but
for now, we're only just there.
And so saying a URL at a phone
is usually a hilarious thing
to do in public and
a frustrating thing
to do in private.
I recommend you
try both sometime.
So we don't have access to a
lot of these UI surface areas
today.
And it all gets back
toward whether or not
we're first class.
Are we part of the ecosystems
top level affordances or not?
And if we are, being first
class has real advantages,
and so it's worth asking
what do we need to get there?
What do we need to do to
actually get ourselves
to become first class citizens
in the most important operating
systems that we're
are all using?
So we've looked at
this problem quite hard
over the last couple
of years, and we
started by understanding
that we all
need to be building
things that work offline.
We all need to be building
things that just work offline.
And the definition here of
work is a little different
than you might imagine.
I'm not asking you
to build things
that work offline in the sense
that all the data is always
cached upfront and
it was done by magic.
No, I'm asking us
to get to a place
where we've got
basic equivalence
with the frustrating
native apps on your phone
that launch and then fail.
It would be great if it was the
application that was delivering
the bad news about what just
happened to the network,
but maybe presenting you
with the previous state,
as opposed to a
situation where you're
looking at a blank
white loading screen.
The white loading screen
is perhaps the worst part
of the web experience
today because we
can't think about
web applications
as being trustworthy yet,
so we need to give ourselves
the ability to build
offline that just works.
And we need access to system UI.
We've heard over and
over and over again
from you that access to the
placement in the home screen
and the ability to
build applications
that you can Alt-tab to is
a critical differentiator.
It's part of what
it means to build
an application versus
build a website.
And we built up a whole series
of stories and expectations
around applications versus
websites premised, I think,
on the inability to be part
of that top level affordance.
Being in a tab switcher
the natural way actually
has real power, and I'm
very excited about what's
happened in Lollipop
as a result.
And I think we need
faster and better access
to powerful capabilities.
There is a whole series
of applications today
that make a ton of
sense on the web
and really not anywhere
else for lots of reasons.
But there's a whole
series of applications
that you can't build.
The application performance
work that you're seeing out
of the Silk team
and the work that's
happening with asm.js
and the ability
to accelerate regular
plain old websites
and make them work very
quickly is massive,
but it doesn't necessarily
open up access to new hardware,
and sensors, and
capabilities in a way
that I think we all
kind of want to see.
We'd like to be able
to keep the pace.
We want portability, but
we want to keep the pace.
And that's a place where
I'm hopeful that some
of the things we're
going to show you today
are a good down payment.
So what would it be like
to actually have a web app?
An application that feels
like an application,
but comes from the web, and
can still be on the web?
It's a little bit
like a black swan.
If you haven't
seen it before, you
might have not theorized
that it could exist.
And I'd like to submit that most
of us haven't seen it before.
Most of us have dealt with
PhoneGap, or Windows 8,
or Chrome apps that have
tried to give us applications
in our native
application ecosystem
that are built with
web technology.
And I think I can speak
for everyone who's
a web developer
here today, and say
that HTML, and JavaScript,
and CSS are not
the best part of your day.
And so someone coming
to you and saying,
hey, I built a new system that
will let you build applications
with HTML, and
JavaScript, and CSS is not
perhaps the most
exciting proposition
that anyone has given you.
If, however, they
said to you, hey,
I made it possible for
this indexable, linkable,
searchable, easily
shareable, friction
free application platform
that we've deliver to you
to work really well.
And as a first class
citizen, when you want it to,
I think that's compelling.
I think that's a better story.
And yes, HTML, and
Javascript, and CSS
are key enablers of that story,
but they aren't the story.
So we need to get
back to a place
where we can build
something once.
Build it and deploy
it to the web
without awkward
packaging steps, without
intermediate gatekeepers
that add friction
to the process of
sharing something.
And get to a place where
an app-- a real app--
is also just a real website.
We need to see these
things in the wild
before I think
people collectively
come to understand what
they're going to be.
So what would a good experience
for this be like today?
Let's just see that you took the
set of things that the web is
currently good at
and the set of things
that apps aren't
particularly great at,
and you looked hard at
them and said, well,
what part of my life
could be made better?
I was thinking
about this question,
and it occurred to me that
it just happened to me.
I was in New York for
the Velocity Conference
a couple months ago, and
it's a great conference.
I got to talk about
performance, and ServiceWorkers,
and all sorts of
my favorite things.
But after the
conference the next day,
I had a little bit of
time before my flight,
so I stopped in to the
Google New York office
to hangout with some
people who I don't
get to see very
frequently and who's
project I'm interested in.
And so we got lunch, and we got
to talking, and I looked down,
and I was late for my flight.
I did that.
Nobody else did that to me.
I did that to me.
But I needed to get to
JFK, and public transit
was going to be like
an hour and change.
And if I took a cab and
there wasn't any traffic,
it might have been 45 minutes,
and I could just make it.
And then this happened.
And this happened not just once
inside of downtown and midtown.
This happened basically all
the way out to the airport.
But luckily, I was stuck in
one of New York's new taxis,
which, despite having looked
like an elongated in the back
and maintaining the wonderful
yellow color of New York
taxis, which makes
it easy to spot,
has kept the quaint
feature of New York taxis
wherein your knees are
introduced to your face
significantly before you
even get on the airplane.
I just think of it like a warm
up for getting on the flight.
It's nice to see that
some things don't change.
So I wasn't going to make
this flight basically.
And had I known that
I was in real trouble,
I could have downloaded an
airline application that
might have notified me that my
flight, as I found out later,
was delayed.
That would have been
great information.
And in fact, I did find that
out at some point in my hour
and a half trip to the
airport in the back of a cab
wherein I was studying
the pattern of the jeans
that I was looking at.
And not having had this app and
not having it notify me made
me really stressed out.
So I was calling my
wife, and we were
trying to figure out, like
oh, can I get another flight?
It just wasn't good.
So when I found out that
my flight was delayed,
it was a breath of fresh air.
It was like one of
the best things that
had happened to me in a long
time because I got to go home.
Now I had used the
airline's website,
and the airline's website
is actually incredibly full
featured.
The airline's website I
already have a login to.
Chrome has synchronized
my passwords to that,
so that's pretty good.
So anywhere that I
login to their website,
I've got access to all of
my history, all of the stuff
that I've done with them.
But I use this website
relatively infrequently.
I use it whenever
I want to travel--
and hopefully that's
not that often--
or when I'm looking for flights.
But it already
knows all the state.
So it's a little bit punitive
to need to go to an application
when the website
could just do it.
Now I could've used
their mobile website.
And as you know,
mobile airline websites
are mostly just practical jokes.
They're designed to give
you the feature set that
looks tantalizingly close
to being what you want,
but in a different URL,
so none of the other stuff
actually works.
So it got me thinking,
what would it
be like to actually have
an airline website that
did just sort of work?
So if we can show-- yeah.
I think we're good.
Great.
Do we have video
from the-- bingo.
Great.
So what would it
be like to actually
have sort of a modern
website for a modern airline?
So this is Polymer
Air, and Polymer Air
is built with a beautiful
Polymer components.
There actually aren't
that many of them.
This was relatively
straightforward to put
together.
And I can do all
the stuff that you'd
expect to do on an airline, and
this is the exact same website
as the desktop website.
It scales up and down.
It uses responsive design using
the Polymer responsive design
components.
That's just sort of baked in.
This is a great system.
So I can come in here.
And imagine when I
check in-- let's see.
One, two, three, four.
I was going to check in, and
my last name is Russell still.
Yes.
I can spell my name mostly.
OK, so let's say I'm going
from San Francisco to London,
and I'd like to know when
I check in about updates
to my flight.
No, I really would
like to know when
I check if there are
updates to my flight.
By the way, you're looking
at a very, very fresh build.
This is the
inadvisable live demo.
Oh, sad panda.
We'll come back to
this in just a moment.
So the mobile
website for-- really?
[LAUGHTER]
This wasn't meant
to be nail biting.
Yes, the inadvisable demo.
So let me show you some
other stuff that does work.
Can we go back to the-- great.
So in today's
Chrome Dev channel,
we can build web apps like Jake,
our beautiful and wonderful
moderator's train to thrill
demo that work offline.
So this is a web app
that Jake has built,
and I'll show you
more about it later.
But let's say that we're
somewhere in San Francisco
where Wi-Fi and network
connections are--
at the home of
Silicon Valley where
getting Wi-Fi is a pain in
the butt-- are just like that.
This site still works, right?
In fact, I can go, and I'm
going to swipe it away.
Kill that.
Kill that.
And we'll come
back to Chrome Dev.
And this site is still working.
I'm in airline mode.
This site absolutely works.
And so I can get back to
the status that I had.
So let's say I go back online.
And like any good
application, it's
telling me what the
status of the network is.
It doesn't actually know.
That's the thing
about being offline.
You don't really know if
you're offline or not.
It would be nice to
in a definitive way,
but the only way
you can really know
is by checking in your
application to know if you are.
So when I refresh stuff now,
I'll see the updated content,
but notice that
this thing didn't
stop showing me anything,
and it didn't give me
a blank white loading page.
It showed me
exactly what it knew
about the state of
the world, and that
caused us to be able to show
the user, say, for instance,
they're boarding pass if
we were an airline-- if we
had an airline
website that worked.
Just going to go with that.
So in the Poly Air system,
what we really want
is the website to be
able to come back to us
and tell us that our
flight was delayed.
It would be wonderful if when
we register for a push message
and at some point later our
flight happens to be delayed,
it was the website that
told us, because I'm
going to be sitting
here with this website.
It would be best if, in fact,
the website decided to tell us
while we were doing
something else.
I think that would
be pretty swell.
And in fact, what we're
looking at here today
is a build of Chrome that
has push notifications
and works offline.
And it's told me-- and
I probably was actually
going to notice that that
happened because it showed up
on my watch.
[LAUGHTER]
[APPLAUSE]
And in fact, if
I go-- let's see.
If I come back to
that-- oh come on.
Oh come on, Android.
Oh, really?
If I come back to that,
and I swipe that away, you
we'll see that the status
is swiped away here too.
This is a real
native notification.
All right, back to the
safe waters of Chrome Dev.
So that's a real thing.
That's a real thing that
I think most of us want.
We want the ability to
reengage users where they are.
And in fact, we also
want the ability to you
take applications like this and
sort of save them all the way
to the home screen.
Darren alluded to
earlier what we're
going to be doing
to make it easier
for you to add stuff
to the home screen.
But when you do, it
sure would be great
if these things showed
up at the top level,
and when you tapped on them, if
they came back as full screen
applications that didn't
require a URL bar when
you didn't necessarily need one.
And when they show
up in your task bar,
they should show
up as themselves.
They shouldn't show up
as just another web tab.
This is all stuff that
we're delivering today,
and I'm going to show
you how this works.
But this works, and you
can do it too, so hurray.
Can we go back to
the Chromebook?
Do I need to do that?
By the way, I've done love the
live demo thing exactly the way
that everybody who knows what
they're doing would tell you
not to do it, which is not just
have a dependency on a network
and not just to have one
device that you're demoing,
but to have multiple devices
and then have those devices not
be the ones that are plugged
into the video screen.
So if you find yourself
doing a live demo,
I suggest that you
take tips from me
and not do it they
way I'm doing it.
Got lost, I see.
Yeah, so I think the most
important part of that demo
isn't that we built a
website that works offline.
That's something that we've been
able to do for a little bit.
The most important
part of that demo
is that we built a website that
works offline occasionally.
We built a website that I didn't
have to interact with a lot,
or I didn't have to repackage.
I built it in the
natural way, and then I
was able to add the
offline capability to it
at some point later.
As I'll show you
in just a moment,
ServiceWorkers enable you
to build web applications
that-- ServiceWorkers enable
you to build web applications
that you can upgrade
with offline capability
if you build them the right way.
So the most important part
of building your application
the right way is-- do we
have the Chromebook back?
With the slides?
Yeah, great.
Here we go.
So the most important part
of building your application
the right way-- I apologize
for the jank here--
is that you build a
real web application.
So let's see.
I want to build a
new tab, and I'm
going to
polyair.appspot.com, which
is where this demo is hosted,
and you can try it out today.
And if you're using
Chrome Dev today,
all of the offline capabilities
should work for you,
and they will work
for you in beta soon.
So this is a regular website.
This is not something that
I built just for mobile.
This is not a
separate code base.
It deployed like a
website, and in fact, I
didn't have to package
up my resources
in a new and unique
and potentially very
special and not the
best ways kind of way.
So this is something
that I use infrequently,
but I want to get
back to it easily.
And on a desktop, that's easy to
do because I've got a URL bar,
and I've got a
search system there,
and it's really easy to use,
but typing queries into a phone
is not the best way to do it.
But I want to be
top level here too.
So I'm just going
to close that up,
and I'm going to come back
to this application which
I've saved to my desktop.
We're going to
start asking users
whether or not
they want you to be
able to save this
thing to the desktop,
but today you're able
to do this manually.
But in the very
near future, users,
if you build your
applications the right way,
will get asked by
us whether or not
sites that they interact with
frequently that are built
using ServiceWorkers and
that have the right metadata
want to be treated
like applications.
And this thing is
a real application.
We want it to be a
real application.
And what you'll notice
here is that the top level
UI is different.
There's no URL bar here, but
I can see what the URL is.
And in fact, the
Chrome Dev summit site
is built the same way.
This is also a site that
has a ServiceWorker,
will work offline
for you, and is
built to be a standalone
application, which
means that I can Alt-Tab
between them the way I've always
wanted to between my web apps.
It's not lost in
the sea of tabs.
It's its own standalone thing.
This is the sort of
power that, I think,
you really want
when you're trying
to become that black swan, a
website that actually finally
is an app.
What does it mean
to be top level?
Well, not only are
you in the bar there.
You're over here.
You're in the App Launcher.
You're where users are looking
to get back to their stuff.
You're part of the easy
recall mechanisms that
are built into
operating systems.
You're part of the tab switcher.
Your icons are the right
thing in the right place
all the time.
Great.
So let's talk about
how we did that.
Can we go back to
the other slides?
Yeah.
Yes.
Great.
Thank you.
Meticulously rehearsed
and flawlessly performed.
So that was just the web.
I think the key thing to take
away from what we've just seen
is that what you were looking
at was a website, right?
You deployed it the same way.
It has URLs.
All of the states inside
of that site are URLs.
You didn't have to package it.
You didn't have to build a
separate application container.
You didn't put it in a store,
not even the Chrome Web Store.
You built a website, and then
it turned into an application
because the user chose to
turn it into an application.
It's a thing that they
thought was valuable to them
and wanted to keep, not
a thing that you thought
might be valuable to
them and wanted to push.
This is the key to doing
engagement well, I think.
But let's figure out how we
actually pulled that off.
There's three
components to this.
The first is a ServiceWorker.
You're going to need
ServiceWorker for everything
I show you and pretty much
all the new capabilities
that we're going to add to
the platform in the future.
So you're going to need that.
Manifests, which eventually
will point at ServiceWorkers.
And the push notification
API was a part of this.
Push notification API isn't
shipping when ServiceWorkers
initially launch later
this year in Chrome 40,
but it will be coming soon.
And some of the
details of the code
I'm going to show you work
today and work in Poly Air
repository, but those will be
changing, and so stay tuned
for those updates.
But let's talk about offline.
Offline happens, and when
offline happens and you
know that it's offline,
you're kind of bummed out,
but it's nice to know.
The worst part is
when you don't know,
because the very worst kind
of offline isn't offline.
It's sort of kind of online.
So I lived in London
during the 2012 Olympics,
and so as a wired
modern city, London
decided that it was
going to put Wi-Fi
in all of the tube stations.
You heard that right?
The stations.
So what that means, of
course-- for those of you
who are laughing
that you already
got this-- is that you could
be in the station waiting
for you're train, start loading
a web page or something else,
step into the train, and
be moving two minutes later
to the next station.
Meanwhile, TCP has dropped out.
It just doesn't know it yet.
It's got a two minute window.
So you're sitting there
watching maybe a white spinner
or blank page trying
to load, and then you
get to the next station,
where your phone is furiously
trying to reconnect to
the same network, which
was made available
in that station too.
And maybe it's busy, or
maybe you don't get on it,
or maybe you get on it, and
then you try to tap things.
But London is a modern city.
Those doors close quickly,
and you're on your way again.
You can play this dance
most of the way to Heathrow,
by the way, from central London.
You can maybe try to load
the same news article
with 700 kilobytes
of JavaScript at top,
which are loaded off the network
and not out of the cache,
is not my favorite dance.
So enter the ServiceWorker.
The ServiceWorker is a
programmable in browser proxy
that lets you decide
what to do, not
the first time you visit a web
page, but maybe the second,
third, and fourth times
that a user visits a web
page after you've decided
to install yourself.
The ServiceWorker has
control over the cache,
and it has the ability
to mediate pretty much
all conversations
with the network.
In the past, we've attempted
to solve the offline problem.
And by solve the
offline problem,
I mean we've been trying
for a very long time.
Who remembers Google Gears?
Wow, you scars are
as big as mine.
All right, so Google Gears
gave you an in browser ability
to cache files.
It was called local server,
but it wasn't a server,
and it wasn't programmable.
It gave you a list of files
that you could put in,
and it would dutifully
hold on to them for you.
We also implemented
App Cache, which
allowed you to give us a list of
files which we would download,
and then dutifully
give them back to you.
But we also didn't
let you program it.
And so having not solved the
offline problem twice for you
now, we've decided to
do something cheeky
and not solve it.
Instead, we're going
to let you solve it.
We're giving you
actually control over
how this whole process works.
So how you get started?
How do you get out of the gates?
So this is the registration
code for a ServiceWorker.
A couple of things
to note about it.
First, the script that
you're registering here
has to be on the same
origin, and that origin
has to be an SSL origin.
ServiceWorkers don't work
over insecure connections
for lots of boring reasons,
but the exciting reasons
are that it's 2014.
Holy cow.
Get some SSL.
What you'll see here is
that it returns a promise,
and that promise means
that the installation
process is asynchronous.
This code is going to
run in the background.
The ServiceWorker
process actually
goes through a series of phases
once the browser encounters
your request to register and
install the ServiceWorker.
So the browser downloads
sw.js, and when it succeeds,
it'll hand you back a
registration object,
and you can find out
some things about it.
The scope object there
tells you basically
which path in the origin
your ServiceWorker
is now registered for,
and at the root, that's
going to be the root, but that's
more of an advanced Feature
that you probably don't
need to worry about.
Once you're inside
the ServiceWorker,
your code is going to be
run from top to bottom.
So the first phase
is the install phase.
The install phase is an event
like any other DOM event
that you might be
familiar with, and you
can control the lifetime
of this event and say,
I'm not actually ready, and
I'm not actually installed.
Don't count me as being
installed until this promise
resolves.
So you pass a promise into
wait until, and then it goes.
If you do anything here,
if you don't have an event
handler for it,
you'll be considered
to be installed straight
out of the gates.
Note that you could also
add items to a cache.
Now I said that we had tried
to solve this problem for you
multiple times before by
giving you the ability
to generate a very
long list of things
and then put them in a cache.
It turns out you
probably want to do that.
It also turns out
that you probably
don't want to have
just one cache.
We learned this the
hard way multiple times,
and we apologize
profusely for it.
But we're giving you the ability
to add lots and lots of caches
and control them and
version them independently,
but you have to do that.
And this is the sort
of code that you're
going to be writing
to get that done.
So you can add a
list of resources
to a particular cache.
But also notice that this API
is incredibly promise heavy.
And if you aren't familiar
with promises, Jake,
once again, has written a great
article about how to use them
and what to expect.
But we partially
designed the promise API
in JavaScript and
in the web platform
to support ServiceWorkers,
so should be no surprise
that you're going to see
it used all over the place.
It's also possible to import
third party libraries,
your own libraries, obviously.
And there is going to be
in the initial release
of ServiceWorkers
in Chrome 40, you're
going to want the ServiceWorker
cache polyfill that'll
add a couple of extra
methods to the caches,
but caches are available
natively in the first release
of ServiceWorkers
later this year.
But these scripts are
going to be cached along
with the ServiceWorkers script.
When you download
sw.js, the browser
is going to go fetch
these resources
and cache them together.
They come down as a
package basically.
And in fact, this is how
you can do collaboration
with third party scripts.
You can use import scripts,
which is an existing API
inside of Web
Workers, and you can
call out to third party CDNs
or third party resources
and use those inside
of your service worker.
This is a great
way to collaborate.
And you have programmatic
control over requests.
You can handle fetches,
and in fact, you
could handle fetches
multiple times.
So let's say you pull in maybe
a third party plus ServiceWorker
snippet using import
scripts, and it
wants to handle only
requests for plus.google.com.
It can do that, but you can
also handle the main requests
for your resources using
multiple event listeners.
So this is pretty good.
And you'll note the
return to respond with.
It's often the case that you
don't know exactly what you're
going to want to do in
response to a request that
comes to your ServiceWorker.
That's OK.
You have some time
to do it, but you
have to tell us
that you're going
to have to take time to
go get that work done.
The reason for this
is that ServiceWorkers
can be killed at
any time basically.
Whenever the ServiceWorker
script is is quiescent,
whenever it's not
doing any work,
we reserve the right
uniformly and unilaterally
to shut it down.
And in fact, we're going
to do that aggressively.
We're doing this to
preserve users batteries
and ensure that the memory
usage of service workers
is low in the common case.
But the side effect
here is that you
need to not be
keeping global state
inside of your ServiceWorker.
If you are, it's
going to get killed,
and you're going
to be surprised.
The good news is
that the DevTools
simulate this quite
accurately today.
You can be happily going along
debugging a ServiceWorker,
and it'll die out
from underneath you.
Not the best
debugging experience,
but at least it gives you
a sense for the lifetime.
So this is a simple
pass through proxy.
There's a new fetch API
inside of ServiceWorkers.
It's the XHR that
you've always wanted.
You're welcome.
It returns promises, and it
takes a request as the key.
You send in a request, and
it hands you back a response
object.
Also response and
request objects.
Hey, wouldn't it
be great if we had
those as opposed to
manually factoring those
in on a per-library basis?
We've added too.
There are some batteries
included, but just enough
to let you do your own thing.
So this is the simplest read
through proxy you can imagine.
You can do something like this
to, say, get real user metrics
in terms of runtime performance.
Obviously, the navigation
timing and resource timing
APIs give you a
lot of that today,
but if you want to do
something specific and custom,
here's a great place to do it.
It's also the case then you can
construct your own responses,
as you see at the bottom here.
We're looking at an event
handler at the bottom that
creates a new response
object, passes
in the content of that resource,
and sets status and headers,
and then responds with
it programmatically.
You can imagine doing
client side templating.
You can imagine doing your
own parsing and processing
of responses that come
back from the network.
All this stuff is possible
with ServiceWorkers,
and it's relatively
straightforward.
I am incredibly excited to
see what you do with it.
I'm also a little bit fearful.
But incredibly excited.
All right, so
remember that cache
that we populated earlier?
It's possible to get an
individual cache object out
of the caches collection, but
you can also match globally
against a single request,
and matching globally
against a single
request allows you
to take the first
thing that comes back.
This is a nice, easy
to use way of saying
if you have something in any
of the caches that matches
this request, hand
it back to me.
But again, it's asynchronous.
The match operation
returns a promise,
and when you get it back,
if it's in the cache,
you'll get an object.
And if it's not in the cache,
you'll get null or undefined.
And that is to say
that, in promise speak,
something not being
in storage isn't
the same thing as
an actual exception.
You'll need to handle
exceptions separately here.
So let's talk about what
happens if I populated a cache,
but my application comes
through and it needs something
that it doesn't already have.
This is read through caching.
It's a little bit simplified
from what you're actually
going to want to do.
But basically you can fetch
it if you already have it,
and then you can put
it back in the cache,
and then respond with it.
This is really straightforward
inside of the ServiceWorker
API, once you sort of wrap
your head around promises.
But aside from that, you
have all of the power
to do all of the things that
you wanted to do at run time.
You didn't have
to be omniscient.
You didn't have
to be omnipresent
with all the developers
on your team.
You can actually
sort of clean up
some of their errors in
this sort of situation
and do things for them to
make sure caches are actually
populated.
So let's talk about
performance for just a minute.
This is a slide from Ilya
Grigorik's talk at Velocity
last year, and it talks
about the lifetime of the one
second budget that we'd
like to give ourselves
if we're actually going to
do the right thing by users.
One second is a long time.
It's a very, very,
very long time
when you think about
how fast CPUs are
and how many operations
we can actually get done.
But from a user,
one second is really
where you start to get annoyed.
One second is a bad place to be
if you're not giving something
back.
And on the web today and
specifically the mobile web,
you blow out that one
second budget very easily.
And in fact, if
the radio is dead,
and you're in a cold
sleep state on a phone,
you can blow out that one second
budget just starting the radio.
You'll never have a chance.
You'll never be able
to get out the gates.
You won't even be able to
look up DNS in that one second
if you're a 3G connection and
you're in a deep sleep state
and at the network level.
So remember that you may already
be behind your one second goal.
And then you have to
add an RTT for DNS
if you don't already have it
in the cache or it has expired,
and RTT for TCP set up,
and RTT for HTTPS set up,
or an RTT or five, and then HTTP
request and response set up.
This is pretty bad.
This is to get any
bytes on screen
if you're going to the
network for those bytes.
This is a very bad place to be.
And this is the place that
we're all trying to live in.
By the way, we-- you
have done a heroic job
in trying to get your mobile
websites to load fast,
but the deck is
stacked against you.
This is a bad place to be,
and we need to do better.
So this is, again,
Jake's Train to Thrill,
and this is a side by side
comparison of it loading
the very first time, and then
it loading with a ServiceWorker.
The first time is on the
left, and the ServiceWorker
is on the right.
What you're looking
at is those bytes
were on screen immediately
in the ServiceWorker case.
And that experience in the
left hand side isn't great,
but the right hand
side experience
is what happens
every single time you
come back to the application
after the first time.
Isn't that better?
Isn't that what we all want
out of the web that we're
interacting with and the
applications that we interact
with?
I think so.
All right, so let's
talk about how,
as you're starting to build your
site with the ServiceWorker,
you're going to make sense
of what's actually happening.
Can we go back to not
the phone, but the pixel?
Great.
Bingo.
Thank you.
One of the things that we
have added in-- oh right.
Let's see.
I'm going to add
USB debugging here.
One of the things we've added
to Chrome in recent years--
are we displaying?
Great.
One of things we've added
to Chrome in recent years,
which is huge for debugging
on mobile, is Chrome Inspect,
Chrome://inspect.
And that will show you
things like all the pages
that you're
currently looking at,
and will let you expect
them immediately.
But today it also
is going to allow
you to inspect ServiceWorkers.
So these are the
local ServiceWorkers
that I'm looking at.
The Chrome Dev summit site
is going to work offline,
and it's got a
ServiceWorker, and we
can inspect it in
the normal way.
It's just DevTools.
That's pretty great.
And we can do the same thing
for the Poly Air ServiceWorker.
And you can see that
this is a ServiceWorker.
It's got a global scope.
It's got a bunch of
stuff we've added,
but it's actually
a very small object
compared to what you
get in a document.
So this is a much smaller API
than what you see in the DOM.
But IndexedDB is available as
storage-- not local storage--
and you have the ability to
work with it in the normal way.
But the interesting
part comes when
you start to work with devices.
So let's go back here, and
let's look at my Nexus.
Because the DevTools team has
done such an outstanding job,
it's possible--
when this works--
to both see what I'm
looking at on the phone
and to start debugging it.
So I can drive this here.
Right?
Cool.
And I can go to the
ServiceWorker internals
page of the device itself.
So Chrome.
ServiceWorker internals
is going to work
both-- I missed a colon.
Maybe I missed a colon?
Maybe I need to load
it from the device.
Bug to be filed.
I can see the
registrations status.
I can see that there's
a ServiceWorker that's
been activated, but stopped,
which means that it was loaded,
and it's now active for a
particular bit of the origin
space but it's been
killed by the browser
because it isn't
doing any useful work.
If I go back, for instance,
to Train to Thrill,
we'll see that the
ServiceWorker state here
goes to something else.
Just one moment.
New tab. train to Thrill.
Now if I come back
here, we'll see
that all the logs are being
sent to you the activated
and running ServiceWorker
at the middle there.
So you can see the login
status that's coming off of it,
and this story is
going to get better
for debugging ServiceWorkers,
but you have the ability
both to inspect them here,
but also to connect to them
over the USB debugging bridge,
so that's pretty great.
All right, can we
go back to slides?
OK, so that's inspecting
and debugging.
It's worth noting that
an application that
feels like an application
that does the sort of stuff
that we've just seen has to
be composed of two parts.
The first is a shell.
It's the thing the boots up when
you initially tap on the icon
or go to the URL.
And the second part is
content, which you probably
want to send down in
the initial payload
when you're first
loading your application.
But subsequently,
you really want
to composing content
into the shell.
If I navigate from
place to place,
I don't want a full page
transition necessarily,
and so I want to be pulling
content and loading it
in with Ajax.
Building an application
in the modern style,
using something like
Polymer, makes this trivial.
The Poly Air application
is really just that.
It's data binding plus
bit of content shell,
and when things change in my
data, things change in my UI.
This is a really
natural way to do it,
and I could certainly
do synchronization
on top of a data model.
And this is how we
need to start thinking
about constructing applications.
Jake's Train to
Thrill is perhaps
the most elegant and
futuristic version of this
because it has server
side logic for smushing
down the initial payload
the first time you go to it,
then it's only
the ServiceWorker,
and then subsequently
launching the show,
and then feeding it data.
And that's sort
of where we really
want to be where we're launching
something almost instantly.
So today, to get ourselves
onto the home screen,
you sort of have to
do this dance where
you click on Add to Home
Screen, you add something there,
and then it shows up like this.
Again, if you build
your site with a service
worker in the manifest, and
it's high quality, and users
like it, and they come
back to it frequently,
you're going to start
to see us asking users
whether or not they
want to continue
to engage with your
site in this way
without necessarily
having to determine
in some inscrutable menu and
without any actual context
whether or not this is
something that they want to do.
We're going to make
this better for you,
and we know that his is our job.
So what is that metadata?
Today this is that metadata.
This is from the
Chrome Dev summit site.
I had to snip a little bit.
You have to do this on every
page, every single page,
at the top of the page.
And by the way, those
are very valuable bytes.
Let's say a user is coming
to your site for the very
first time.
This sucks.
This is bad.
This is in your first
couple of packets.
This is stuff that you wanted
to use to put pixels on screen
to tell the user that something
else was going to happen
or give them the answer
in a best case scenario.
This regurgitation over
and over and over again,
which is subtle and breaks
easily, is a bad thing,
and so we're replacing that
with a new web manifest format
that's being specified
at the W3C in conjunction
with Mozilla and others.
But what you do instead of that
long winded thing at the top,
is instead to put
your theme color,
if you want one, with
a link to a manifest.
And that link to a
manifest is something
that you can point you from
any document in your origin.
And it's going to include
all the stuff you really
want, but it can be extended
with other stuff later.
So for instance, you'll see the
bottom there is GCM sender ID.
That's what we need in
our demo application
to make it possible for
the notification API
to understand-- or
the push notification
API to understand
where you're actually
coming from with regards to the
back end of the push system.
We hope not to need
this in the future,
but for now, it's
extensible, and we
to start to use this for
more and more features
that don't fit anywhere
else in the platform.
High resolution icons.
A long description.
A location to load,
when you initially
tap on the document
in your launcher,
those are all part
of the manifest,
and you can even control
the screen orientation.
This is good stuff,
and we expect
to this is going to be
a key enabler for making
it possible to build
things that feel appy.
All right, let's get the
push notification bit
because I think that was the bit
that you actually clapped for.
I don't if that was tension
because I did it wrong.
So what you'll see
here again is promises
being used nearly everywhere.
This is a little method
we've put together
to request permission
to do notifications.
This is an existing
API that we're
extending for this new world.
And because it doesn't
already come with promises,
we're wrapping it in a promise.
And again, you can
create your own promises,
and this is sort of
how you can control
inside the ServiceWorker things
like delaying, activation,
or waiting on some
network, or for IndexedDB
response for data.
But we're going to
request permission,
and then if it's
granted, we're going
to vend a promise the
resolves successfully with it.
And I'm not going to
deal at all with how
to do those permission
prompts directly.
My colleague Adrian is
going to talk to you all out
how to do that and
how not to do that.
And I can only say that
if you do it right,
it's going to work
out well for you.
And if you do it badly, you're
going to have a bad time.
So let's say that
we get to the point
where we've got that request.
So we can request it, and
then, as you see here,
request and then then.
We can say
navigator.push.register.
This registration
method is going
to move to a different
location in the API,
and I'll update the appropriate
things as that happens.
But basically, you
get a registration
and then you can send
the registration ID
that you get back as a
part of that registration
object to your server so that
your server can send things
to the backhaul push
messaging system,
and then notify
you on your device.
That's what allowed us to
deliver a message to Chrome,
even though Chrome was dead.
Chrome was listening
for the message
that you sent even though
Chrome hadn't been started
when I received
that push message.
So that's how we enable end to
end push message registration.
All right, on the ServiceWorker
side-- by the way,
there are some push
notification systems
that you may have used in the
past which don't let you start
your application
when you receive
a notification or
a push message.
That's a pretty bad
user experience.
When, let's say, I am in a tube,
and it's going from hop to hop,
and I've gotten just enough to
know that something happened,
and then I tap on it, and it
doesn't know anything about it.
Instead, what
we're doing here is
we're allowing you to
handle the push message
and then create a notification
yourself, knowing that you
probably want to do is take that
data, and put it in a database,
and make it available
for your application
when it starts back
up again offline.
There's nothing more frustrating
than seeing a notification that
has everything that you
wanted to see, and then
go into an application,
and then telling you
that it doesn't have it.
We should do better than this,
and our model allows that.
So the way you do it is
that you get data back
from the event for
the push message,
and you can create
a notification.
The ServiceWorker true thing
may change in the future,
but basically you can
create a notification
from the background context
if you have previously
requested it from the
foreground context.
You're not able to make
that request for permission
from inside the
ServiceWorker, so make sure
you do that in your
application from the pages
that you're looking at.
That makes sense though, right?
The users looking
at your app, you
should be requesting
permission to do things
from inside your app.
And in fact, you get events
back to handle the stuff
that just comes down
the wire or when
the notification
is interacted with.
This is a natural
outcome of the fact
that the ServiceWorker could
be killed between when you send
the notification and
when it came back to you.
So it's a good thing to use
the notification object that
comes back from the notification
click to go handle things.
I wanted to just let you
know that while all of this,
I think, is
compelling, and I think
is going to enable
you to deliver
amazing applications in
the very near future,
we're just getting warmed up.
Dare I mention background
synchronization
and it's a high priority
for us in the near future.
We know that you want to be able
to go update your application
when you're connected
to power and a network,
and maybe the user is asleep.
We know that you want alarms.
We know that you should be
able to make an alarm clock
application on the web.
We understand that.
And we're working hard to make
sure that those sorts of things
are available in the future,
and this is just a down payment.
So we're listening.
The slide deck will be
made available, as they all
will Jake's "Is Service
Worker Ready Yet?"
website is the
authoritative place
to look for information about
the status of the various APIs
that are being added
and to understand
how it's progressing
in different browsers.
So we're not the only
ones who are implementing.
We've designed this system in
collaboration with our friends
at Mozilla, and
others, and Samsung.
And we're excited that
they're implementing too.
So thank you so much for
your time and attention,
and I'm excited to
talk with you about how
we're going to
make real web apps.
[APPLAUSE]
