From AMP to PWA: Progressive Web AMPs (Google I/O ’17)

From AMP to PWA: Progressive Web AMPs (Google I/O ’17)

morning everybody. Good to see you all here
and on the live-stream. Good morning around the
world, if you’re joining in. Welcome, my name is Paul Bakaus. I’m a developer advocate
working on making the web faster and user-friendly and
currently with my focus on accelerated
mobile pages, AMP. And I’m here to tell you
about a combination made in heaven, as I would call it. And what I’m talking
about is the combination of AMP and Progressive Web Apps. Now, AMP makes the
first hop blazing fast. If you’ve experienced
it before, you know that it’s usually the case. But in Progressive Web Apps
enable amazing reliability and engagement that you will
only see from a native world. But that’s just on the surface. So on the surface, the
combination kind of makes sense. But then we have to
start from the beginning. Because once upon
a time the story starts with a
modern-day web developer in 2017 with a growing
[INAUDIBLE] syndrome the feeling of drowning. And so in 1999, if you created
a web page, what you did is you created some HTML markup. You added some CSS. And then you hit
the publish button. You had some really
cheap server. There was no slash-dot anything
to have the slash-dot effect. So really it was fairly good. And I felt like I
could do anything. I felt like, oh yeah,
this is amazing. I’m connected to so many
people around the world. And it’s free
entry for everyone. But now let’s look at 2017. So create a markup. You add some CSS. Then someone tells you to
[? defi-choose ?] a build tool and make sure you
choose the right one. You add Babel, Webpack
and obviously, React, because I heard
millennials like React. And then so many
other things that you have to do to actually
be competitive in today’s landscape. And then, so yes, being a
modern web developer is hard. But in fact, if you’re looking
at it from a company angle– you know, what does
your company, let’s say, a publisher– what is your company
trying to accomplish? And what do they need to do? Now you go one level up, and
you see it gets even worse. Because you have a number
of different deploy targets. The mobile web, the desktop
web, native Android, native iOS, Instant Articles,
Apple News, and so on. So there’s a number
of growing ecosystems that you need to support. And now I’m here to tell you,
to add to more to the roster, and you’re like, oh no. So yes, I get it. I get it. But hear me out. So let’s take a zoom-out
world view, a bird’s eye view, onto what we’re
actually trying to do. Now if you look at an e-commerce
case, what we’re actually trying to do, regardless of
technology, I’ll take a guess. You want to sell stuff? You want to sell lots of stuff? To sell stuff, you need to
bring your product landing pages to lots and lots of
places, where they’re seen by millions of people. And landing on your
browser and product pages should be effortless
and instant. And finally, the payment process
should be effortless and simple as well. The user should automatically
be inclined to come back and buy more over time
through re-engagement. That’s the kind of
experience I want. I want to start fast
and then stay fast. So why does AMP solve
part of this problem? Well I’m just going to recap
briefly why that matters here. So think about
your apartment key. Would you give a copy
of your apartment key to all of these people? Uh, uh. Well there’s usually one
or two that say, yeah sure, it could turn into
an epic house party. However, that’s
really optimistic. I think this scenario
is way more likely. However, on the web,
there’s an ongoing challenge of having a lot of monetization
and user acquisition methods in play versus the
user experience. And this happened because we’re
giving the keys to everyone. We’re giving the keys
to everyone for everyone to our web-pages. So as soon as we add a script
from a third-party to a web page, all bets are off, right. If you don’t trust– if you
can’t trust that source– they could do whatever
they want on your web-age. It is really like giving
a key to a stranger. And so what we get
because of that are slow loading pages, non-responsive
content– content that’s shifting around. That is really, really not
really great to experience. And we just had that. So I’m going to skip this. Now the current
situation is pretty bad. We have over 200 server
requests per mobile web page, on average. And 19 seconds is the
average mobile launch page time over 3G. Now out of those 19 seconds,
77% of all mobile sites take longer than
10 seconds to load. But don’t worry, it gets worse. In fact, if you look at that
10 second number in particular, it’s really important. Because at 100 milliseconds,
an interaction, for instance, clicking
a button, feels instant. One second, it
still feels natural. You still have
your context model. But then at 10 seconds, you
lost the user’s attention. And yes, that has been
measured multiple times before. The fact that after 10 seconds,
if you load a mobile page, almost all users drop off. Now if you’ve been listening
to the previous stat, yes, that means 77% of
all pages are likely never seen on mobile. So that’s why we created AMP to
actually combat this problem, to bring back the beauty
of the mobile web. And so we have three components
in AMP, the AMP HTML, which is a super-set
and subset of HTML, but adds new components but also
restricts some of the things that you can do. And then we have AMP JS,
that powers those things. And then we have the AMP Caches. Now just two quick
examples what AMP does, a few of the
things that it does. For instance, it can
prioritize content loading. So it knows exactly
where everything is rendered on a page before all
the external assets are loaded so that we can pre render
the “Above the Fold,” and not render anything else
“Below the Fold.” And the caches can then use
that– the platform that uses the caches to
deliver your AMP pages– can use that to
smartly pre-render quite a set of pages. So if you’re arriving, for
instance, on Google Search, and you get the
top-stories carousel, which is powered by AMP,
some of those links are often pre-rendered before
you click on them, which is why they feel so instant. And now if we go back one step
and look at this comparison that I did before of
1999 versus 2017, how does this look like an AMP? Let’s have a look. Yeah, I think it
looks way better. In fact, that’s what you do. You create an HTML markup. Because we have high level
components like accordions and all sorts of things
in the HTML markup, you never write JavaScript. So you create HTML
markup, you add some CSS. Out of it you get a fairly nice,
responsive, interactive content page, if you want to. And then you just
hit publish, and it can be read on a
really cheap server because the caching
infrastructure on top automatically quarrels and
caches all of your content to be displayed in the apps. So you get back to a really,
really cheap deployment model. So why Progressive Web Apps? Well, they’re gaging. They give you push notifications
and home-screen stickiness. And they’re also reliable. They give you offline
access and responsive UI and those other things
that you know usually from the native world of things. And that’s a common reason why
developers built native apps. But in fact, 80% of the time
is spent in the top three native apps on a phone. And this zero number
of apps that get installed on average per month. So that means that it’s very,
very expensive, for instance, through advertising, to acquire
new users through the app store model. And so what we
want, essentially, is a combination
of those things. We want the capabilities of
the native app ecosystem. But we also want the
reach of the mobile web. And we get that with
Progressive Web Apps because they have many of
those features built in. And they’re also
basically a website. So it’s a pretty good way
to get both of those things. So why is the combination
of those two a good idea? They seemingly seem to
attack different spaces on a different level. Well if you just build
a Progressive Web App, then you have the challenge
that your first load is still going to be slow. And the reason is that
Progressive Web Apps really depend on a technology
called Service Worker, a client-side proxy that
accelerates and caches the delivery of your app-shell
of articles, et cetera. But the Service
Worker only kicks in after the second request. So on the first load, you don’t
get those performance benefits. And usually its the
first impression that counts if you
want to get a new user. But then on the
AMP side of things, you get no user-authored
JavaScript. So we don’t allow you to write
user-authored JavaScript, except in i-frames. There’s no customer Service
Worker, no push notification, and no web app manifest when
served from the AMP cache. On your origin,
that still works. But when served
on the AMP cache, you don’t get all
of those benefits. And so that is an order
to be predictably fast. So the difference,
really, on the AMP-side, you get reliable,
instant delivery and optimized discovery, but
no JavaScript, static content, mostly. But on the Progressive
Web App-side, the first delivery
is usually slower. It’s not as easily
embedded as AMP documents. I’ll talk about this later. But you get access to
the latest web APIs. You can do whatever you want. And it supports much more
dynamic content, even. And to combine those
two is what we call it Start fast, Stay fast. And now, of course, you
can forget all of that and simply focus on the
fact that the combo makes for some mesmerizing
[? lead ?] animations. And if you’ve been doing
web animation– sorry– if you’ve been doing
web development in the 90s and early
2000s, I think this one might work even better for you. Wait for it. Mmm. Yeah, OK. OK, let’s not go there. But how do you actually do it? How do you actually get there? Well we have three application
patterns that make it happen. First, I call AMP as
Progressive Web App. Second AMP to PWA. And the third, AMP in PWA. Now, if you’ve been
listening, and I’ve been comparing the two. You’re like, wait, AMP as PWA? We have actually–
for sites that have static content,
mostly, and don’t have a lot of
inter-activity– you can have an AMP that is
both a Progressive Web App. In fact, mynet, who
is one of the leading publishers in Turkey, has
done that with their pages. So what you see here is a
fully compatible AMP page. All of this is AMP with a
full navigation concept, back and forth, carousel, whatever. All of it is AMP. And it also has Progressive
Web App features. So it can be installed
in the home screen, has a web app
manifest, and so on. And, in fact, just
by doing that, they saw tremendous uptick
in quite a few numbers, they got over 25% higher
revenue per article page view. That is really the
important number because that means the
bottom line is better. And four-time faster
average page-load speed. Over 40% longer
average time on site. Over 30% more page views
per session, and much lower bounce rates. So in the end, really,
something worthwhile to do. But you can actually go further
than that with our pattern. You could actually, because
you have the service work in place on
your origin, you can insert anything into
the AMP page that you want– random stuff that
AMP doesn’t like– because you are in control
as soon as the Service Worker is running. Now I had some
nostalgia, so I thought, why not insert some 90s HTML
magic into the AMP website. And I found this
amazing mouse cursor. And this is exactly what I did. So here we go. I’m going to enable
the Service Worker. I’m going to reload. And, yes, I have a fancy
mouse cursor and an animated background, all the things
that AMP doesn’t like. And, first of all,
what have I done? Ah. So you shouldn’t do
exactly that, maybe. But this pattern
still comes in useful if you want to insert ads
that aren’t, for instance, not supported in the
ecosystem yet or other things that you need on
your origin to run. So next is AMP to
Progressive Web App. Now all of this is based on
a technology on a component that we call AMP
Install Service Worker. And the AMP Install
Service Worker, the way– if you’ve
used Service Worker, before, you register it in
JavaScript on your page. And because you don’t
have access to JavaScript, we have an equivalent that is
AMP Install Service Worker. But the cool thing is
that this component also works when your page is
loaded on the AMP cache, let’s say, in the top
stories carousel on Google. It can install the Service
Worker from your site’s origin from your own domain so
that subsequent clicks are accelerated. And the way this looks is the
pattern is always the same. The user discovers
content, the Service Worker installs in the background
while the user is consuming the content, and then the user
is upgraded instantly to a PWA. Let’s have a look at how this
looks in real-world production examples. So first, let’s look
at crossing, or XING, which is a job search
site similar to LinkedIn in all of Europe. And so if the user
discovers content, they check out a job that
they like, they click on it, and then the Service Worker
installs in the background. And now if they’re
actually interested in one of those jobs, they’re instantly
forwarded to the Progressive Web App that can add
push notifications, can remind them to come back
if their job is not available anymore, et cetera. So the next click is
going to be instant. Now, next example. With goibibo, which is a leading
travel search company in India, you get the same pattern in a
completely different vertical. User discovers content. Second page, the Service Worker
installs in the background. Now this page is a page that
just shows you the hotel. But now there’s a get
availability button at the bottom. If you click that
button, again, you’re instantly redirected to the
Progressive Web App that allows you to check the availability. We could have even checked in
advance in the Service Worker if there’s availability so
that even the API call wouldn’t be necessary anymore. And then Rakuten, a
Japanese recipe website that they’ve created recently,
is called Rakuten Recipe. And in this case, same pattern. They user discovers the content,
arrives on a recipe site. And so you browse the
recipe, you realize, OK, there’s a couple
of connected recipes that I’d like even more,
or I want to bookmark this. And then the user is instantly
upgraded to a Progressive Web App. Now with Rakuten, in particular,
I have some stats to share. In fact, if you look at
the different combination of things they’ve done,
it’s quite impressive, in my opinion. So with AMP, they’ve seen over
50% more time spent per user, over 3.6 times higher
CTR within the AMP page, compared to other
Rakuten Recipe– actually, no, two other
Rakuten Recipe sites. And then with add to home screen
with a Progressive Web app feature, they’re seeing over
70% more visits per unique user and over three-times more
page views per unique user once they installed
to the home screen. And push notifications,
same thing. A lot more re-engagement,
three-times more weekly sessions per user
after the first viewing week, four-times after
the second week, and five-times after
the first month. And now this is
really important. With push notifications,
they get 3/4, so 75%, lower bounces for
those users coming in via push notifications
than via social shares. So they’re seeing much
more re-engagement through that channel. OK, so this sounds,
hopefully, pretty good. But there’s still a problem. Now if you copy the URL in
the Progressive Web App, you share or send
it to a friend, then that friend will not go
through the AMP Install Service Worker flow. So they will open the
Progressive Web App without a warm cache. Now what do we do with this? Well, usually you would
have AMP pages deployed on one sub-domain, and you
have the Progressive Web App deployed on another sub-domain. And a link from the home page
leads to the Progressive Web App. Sounds pretty straightforward. However, you can
change that and reuse the same domain, the same
URL space, for both of these. And you can do that because
the Service Worker can intercept navigation requests. So if you click a link, the
Service Worker can say, OK, no. I’m not going to give
you the next AMP page. I’m just going to give you
the Progressive Web App instead, even though
you’re on the same domain. And it’s actually just a few
lines of code to do that. So you check for a
navigation request, respond with a
Progressive Webb App. Now what happens if we do this? A couple of magical things
because without the Service Worker, we still just get AMP. So for browsers that
don’t support it, you always get a
fast experience. And with Service Worker,
you get the combination of AMP in the background
and the Progressive Web App because the Service Worker
intercepts and delivers the Progressive Web Instead. And if you don’t have the
Service Worker and you still want people to lead to
the richer experience– a Progressive Web App
that might not work fully because there’s no Service
Worker in some browsers– you can still do that
with a technology that we call Shell URL Rewriting
that’s part of AMP Install Service Worker. Basically what this
does is it says, detect if Service Worker is
available in this browser. If it’s not, rewrite
the URLs on this site to go to a fallback domain. Now, OK, we have this complete. But now we have another problem. We still have this problem
with our deploy targets. We still have plenty
of deploy targets. And in fact, in this
case, we probably have two content back-ends. We have AMP HTML on one
site and then probably JSON or some other content
back-end for the progress web app that powers the
Progressive Web App. Now that is where the final
pattern comes in handy, AMP in Progressive Web App. And, in fact, AMP pages
aren’t just web pages. They’re ultra-portable,
embeddable, content units that can stand on their own. And if you think
about it this way- if you don’t think about
it just as a web site– some magical things can happen. Because we can
get from this step to this step, where AMP HTML
powers all of my experiences. In this case, the AMP experience
and the Progressive Web App experience. Now one way to do this is to
build an application shell and then use an i-frame. But i-frames are slow. And what we do
instead, because we trust the content as our own
content, we use Shadow DOM. So how does it look like? Without Shadow DOM,
you get one window. For every i-frame
that I initialize, infinite number of
AMP library instance, and then an infinite
number of documents. So lots of overhead to
initialize the AMP library over and over and over
again for every i-frame. But then with Shadow DOM,
you just have one window– one library instance that
we call a shadow AMP– in the top of the page. And it simply connects
to lots of documents and renders them out. So that’s a much cleaner flow. And in practice, the
PWA hijacks navigation clicks, fetches the
requested AMP page, puts the content
into that Shadow Root and then calls
attach Shadow Doc. But this was a slide that
showed it just very briefly. I actually want to show
it a little bit more in detail because we have a
little bit more time today. And, in fact, I think you
can do this in an hour. This flow of inserting
content via the Shadow DOM, if you already have AMP pages,
I think you can do in an hour. Now, if you don’t believe me– let’s do it in five minutes– OK, all right. So, the first thing
that we want to do is– and this is a caveat– we want to have a content
store somewhere that serves as the navigation. So in this case, we need
to have an overview page from somewhere that has a bunch
of links, a bunch of images, maybe. In this case, I just used
yql to fetch an RSS feed from somewhere, which is a
really nice hack to create a compelling demo, I would say. And this gives me a nice list
of articles that I can use. And I used the
Guardian as a back-end. Thanks again for the Guardian
for letting me use their RSS feeds. And so as you can see,
this is what I have so far. So this is just using the
RSS feeds through yql. And so far, so good. And this, again, this
step is not so hard to do. So I shouldn’t be saying
this, but I started on Monday. And so, next one. We add the AMP Shadow Library
to the head of the page in our Progressive Web App. Now, again, this is a
special version of AMP. And then we wait
until AMP is loaded, which is using this
technique that you find in a lot of
frameworks nowadays. So this is just a wrapper that
the code inside this wrapper runs as soon as AMP is
actually fully loaded. And then when you have
that, you fetch the AMP Doc via XML HTP request. And now, again, straightforward. You know the link from
the previous navigation. You know the link
to the full article. You fetch it via
XML HTP request. And then you return, something
that we call response XML. Now, response XML contains a
ready-to-use document object, a not that well-known
feature of XML HTP requests. And I’m not using fetch
here because fetch doesn’t support this yet. This is why I’m using
old-school XML HTP requests. So now we have our actual
document, our AMP document. It’s not rendered anyway yet. But now in step five, we
render it using Shadow AMP. So what we do is we
create a Shadow Root. What this is– what
it means is it’s just a fancy way of saying we
create a diff, a container. And we gave that diff and
called it Shadow Root. Now the AMP Doc
does all the magic. The Attach Shadow Doc
Function does all the magic. So we give it the container
that we just created. Actually, this should
say Shadow Root. So that’s just back on a slide. Then we give the doc that
we just fetched via Ajax. And we gave it the original URL. And then, in this
case, we can also have a function
that notifies us, a promise when the page
is ready and rendered out. Now that’s the basic flow. But there’s a few things
that make it even better. For instance, if you don’t need
certain things in the AMP page because the AMP page usually
has its own side bar, its own navigation,
so it can stand alone. But if you don’t need that
stuff while in embedded mode, you can actually
remove those things before you give it to
the AMP Shadow Library. You just remove the header,
remove the side bar, et cetera. So this is actual
code from the demo. But also cool, if you don’t
want to do something as complex, that’s cool too
because there’s a class that we add to the
body of the Shadow AMP of the embedded page. Which means that in your
CSS of your AMP page, you can use the dot AMP Shadow
page to simply hide things that you don’t want
in embedded mode. So that works as well. And finally, if you don’t
want to remove things, but you want to insert things
back in into the AMP page– features, for instance,
like JavaScript highlighting or something like that– into the embed, you can do that
as well by using Shadow slots. And they provide a path
for progressive enhancement of AMP Docs when shown in
the publisher’s own context. So how does this
look like in action? Let’s have a look. Here we go. So the content experience
is now all powered by AMP. As soon as you click on one of
those links in the overview, the page renders and loads. And because it’s
everything in our control, we have the whole
document available, we can do some really
nifty transitions to animate the windows too,
instead of a full page load. Thank you. Now, finally, let’s
wrap things up. With a Progressive Web App,
with a Progressive Web AMP– sometimes I also call
it PWAMP because I like the sound of it– it’s always fast no matter what. There’s great
distribution built in. It’s progressively enhanced. It’s really just one
back-end to rule them all. And there’s less client
complexity, fewer deploy targets. And to visualize
this last point, again, remember how we had
those plenty of deployed targets before in our previous slide. When in fact, we’re now down
to just three if we want to. We have the PWA shell,
the native shell, and the Native Shell in iOS. And those are just
thin layers that serve as the
application shell that provide a navigation model and
maybe some features on top. But then AMP is the
back-end that runs it all, the content source. All of those could use
AMP as a constant source. And so you support the web,
you support Android and iOS at the same time with very
thin layers of extra code. So finally, a word of caveat. When do you actually do this? Well, you do this when
you have a site that has lots of static
content, for instance. So you don’t want to do it if
you built an XGML because it’s really more like a like
a really dynamic app that doesn’t have landing pages– what we call lead
pages– that are accessed via organic
search or social discovery. So your site has to have
lots of static content for it to make sense. And ideally, you already have
a large corpus of AMP pages. That already gets you
through the first step. And this works extremely
handy if your engineering resources are
constrained or to reduce infrastructure complexity. And finally, you
need to test out– if you haven’t done AMP
before you need to test out– if your content monetising works
fine within the AMP ecosystem. So before I leave
you, and I think I have some time to open
the room for questions, I’m going to leave
this up for a second so you can take
some screenshots. So we have a React
sample app as well. That’s not the one
that you saw today. But it uses React, so it’s
great for millennials. So use the React sample apps
to see how you do it in React. It has similar nice transitions. We just launched
the AMP channel, if you’re not sick
of my face yet. You can see it again over there. And, we just
published a big, new guide about all of these patterns
that I just talked about. If you want to recap
all of those things and go through the tutorials,
you can do that now on With that, I’m going to
open for questions today. Thank you everyone. [MUSIC PLAYING]


  1. 1:50 "Add React (because millennials love React)"
    28:10 "It uses React, so it's great for millennials" laughter

    Huh? What's that supposed to mean?

  2. What was he referring to at 10:45 ?

    "If you've been doing web development in the 1990's – 2000's, i think this one might work even better for you..wait for it…"

  3. Si quieres saber más sobre AMP y PWA te recomendamos ver el episodio 5 de Google P&R

Leave a Reply

Your email address will not be published.