 Hi. Good morning, everybody. Yeah, my name is Paul. I work on AMP. And I'm also on the DevRel team at Google. And I'm really going to skip that mostly, right? Unless you literally just arrived, you've heard about progressive web apps. They have to turn your site into reliable, fast, and engaging experience. But what if you built the most amazing progressive web app and nobody discovers it? It doesn't wait long enough until the service worker has installed your app shell to make subsequent loads snappy. Keep in mind that the service worker is awesome, but doesn't hear about all with the first load. Even though the service worker API allows you to cache away all of site's assets from almost instant subsequent load, like when meeting someone new, it's really about the first impression that matters. If the first load takes more than three seconds, then our latest double-click study has shown that more than 53% of all users will drop off. So half of your audience will never, ever get to see your content. Now, in three seconds, let's be real. It is an already brutal target on mobile connections that often average around a 300 milliseconds latency and come with other constraints such as limited bandwidth and establish a signal. And so you might be left with a total load performance budget of less than a second to actually do the thing. It's meant to do, to initialize your site or app. But don't worry, it gets worse. By the way, if you really want to load in under one second, says Rayl, they're writing that number itself from a book on usability by Jacob Nielsen. Is site does more than three roundtips to server? Well, sorry, you probably failed. So don't feel too bad, though. The overall landscape of today's web looks a lot grimmer. The average mobile page loads in about 19 seconds with 77% of those taking more than 10 seconds to load. Now, the crazy thing about the 10 second mark is that at 10 seconds, actually 100% of all your users bounce. So at 10 seconds, no one will ever get to see your site. And then it's 214 server requests, of 50% of which are at related requests. So at first click, that first impression is what matters. We want to get rid of slow loading pages, but also solve runtime performance so you can scroll really efficiently and other usability issues at the same time. And fortunately, we have a solution for it, or we think we have a solution for it. We call it accelerated mobile pages. AMP short for accelerated mobile pages is an ecosystem consisting of a web components library that allows you to declaratively write HTML. We call AMP HTML, because it's both a superset and a subset and AMP caches. Basically, CDNs are more technically correct reverse proxies that accelerate delivery on top of that. And then so you can do it in two ways, actually. You can either just build one, use AMP like a library, build just one page, and you have one canonical page for everything, or you can use a link to MetaTek and the header, and then just generate two pages in your CMS and create one HTML page and one AMP HTML page. But that's really up to you, whatever you prefer. And in that shell, it turns author pages into a highly portable, fast and user-friendly units that platforms like Google, Bing, or Pinterest can safely and quickly embed. And so it's a really rich and growing library of web components. Now, a lot of the baked-in performance optimizations you could probably do yourself if you're an experienced developer. But the AMP cache onto itself is actually a very important component, not just because it's a free, super-fast CDN. The AMP cache works tightly together with the prioritized loading and static layout system of AMP. Documents served from the AMP cache are much cheaper to pre-render, because AMP knows where each page element is positioned, even before any assets are loaded. So allowing you to load the first viewport without any low priority third-party stuff. And the actual site owner won't ever know about the preload, which is another very interesting point. Super important for privacy reasons, as the site could otherwise write cookies and mark the page as seen. If you're searching for diarrhea on Google, you might not want every one of those pages to actually write a cookie on your behalf and give you diarrhea ads everywhere. Sorry for putting that image in your head, by the way. So AMP pages are really just HTML and CSS. You can't have any user authored JavaScript on the page. That's one limitation. Instead, a lot of custom elements. And sandbox AMP iframes allow you to still do everything if you want to do something like a crazy animated graph or something that is really custom to your page. And then the AMP open source library is the same everywhere. So it's hosted on one CDN URL and you include it from there. And that means it's evergreen. It's highly cacheable. We can upgrade all AMP pages in less than a couple of days, couple hours maybe, even if we have an important fix to do. And it defines the behaviors for those custom elements and manages rendering and resource loading to optimize performance. Now, the important question that might come up in your head is, do you want to go AMP or PWA? You learned a lot about progressive web apps already in the last couple of sessions. And we've been hearing that question constantly. But in order to be reliably fast, you need to live with some constraints when implementing AMP pages. So if you want to go AMP, you won't get the biggest progressive web app benefits on our first click. So from a progressive web app, you won't get that first click experience. But with AMP, you don't have a custom service worker when it's loaded on the AMP cache. So you can't do anything fancy in there. It means no push notifications, no web app manifest from serve from the cache. And so if something isn't available as a component, you can't just hack a script together, for instance, to support web payments or push notifications. Now, those of you that already read about the individual advantages and disadvantages of progressive web app versus AMP have surely struggled with this question before. And on one hand, now, you have instant delivery, almost instant delivery, optimized discovery. But then, again, no user scripts, and mostly for static content. On the other hand, you have, on the PWA side, you have advanced platform features. Of course, you can build everything you want really, highly dynamic, but it's a slower first delivery. And really, again, the first delivery is highly important. And it's not easily embedded in third party platforms as well as AMP. So what if there was a way to combine those two, to really reap the benefits from both? In the end, what I think is what matters is the user journey. The first hop to your site should feel almost instant. And the browsing experience should get more and more engaging afterwards. Now, AMP and progressive web app are both critical components to make that happen. AMP pages for the first navigation and then your progressive web app for the onward journey. Now, let's first talk about AMP as progressive web app. Because I won't cover this in detail in this talk, but it's important to note that many sites won't ever need things out of the boundaries of AMP. AMP by example.com, for instance, which is an examples page that the AMP team uses to showcase a lot of AMP components, is both an AMP page and a progressive web app at the same time. So it has a service worker, therefore allows offline access and more. And it has a manifest prompting the add to home screen banner. Now, you might have heard me saying, well, you can't have those things, but that only means you can't have those things at AMP when it's served from the AMP cache, meaning the first time you might click on it on a platform like Google Search, you won't get those benefits. But the next time you click out, you actually get it. So once you arrive on the origin, the service worker installs and does a lot of fancy things. So when a user visits ampbyexample.com from Search, then clicks on another link on that site. You navigate away from the AMP cache to the origin. The site still uses the AMP library, of course. But since it now lives on the origin, it can use a service worker prompt to install, et cetera. AMP, by example, uses that technique to do just that. But I had some fun on ampproject.org, at least on a local branch. I thought, what if we already have a service worker intercepting? We insert more random stuff into the page. How about things? I mean, we can pretty much do everything we want in that fetch event, right? How about things that AMP doesn't like? Because the cache doesn't see the service worker. It doesn't really care about the service worker. So we can do pretty much everything we want. So I got a little nostalgic. I'm like, hey, why not throw in some 90s DHMR magic? I found this fancy cursor that I think improves my page. So here we go. We are using the service worker panel. We load the page. And yes, I got a JavaScript animated backdrop and a really fancy cursor. And I think it dramatically improves the experience of our documentation pages. So first, did you got what have I done? Second, please don't do this at home. But it's a technique that allows you to make amendments, change what you can do on an AMP page, just insert more stuff. So now to the more interesting bit. Transitioning a user smoothly from AMP page to Progressive Web App. There are two ways I'm combining two. Steps I personally call AMP up and AMP down. AMP up is the background bootstrapping of your Progressive Web App shell while the user is enjoying your AMP page. And AMP down describes reusing AMP pages as a data source for your Progressive Web App. The basics with AMP up are that the first click will be on AMP page, usually served from the AMP cache. And then any links on our page will navigate to your Progressive Web App. So normally, that second click would still be considerably slower than the instant feeling preloaded first click on your AMP page. But it's a powerful component baked into AMP, the AMP install service worker tag. That without writing any custom JavaScript allows you to install your service worker for your origin. So yes, even when your AMP page is served from the AMP cache, it installs the service worker from your origin, downloads an app shell, and bootstraps your Progressive Web App, which means at the time the user reads your article, your Progressive Web App is already loaded and ready to go. And the Washington Post actually does this. That means while the user is reading your article, yeah, actually, I just said that, it can warm up. The service worker can warm up in pre-cache. When a user now clicks on a link on a page or calls to action at the bottom, your Progressive Web App shows up instantly. And Alex Russell called it this pattern, start fast, stay fast. This is what I call AMP-UP. But now you're in the Progressive Web App. And chances are, most of you are using some HX-driven navigation that fetches content via JSON or some other data backend. Now you can certainly do that, but now you have this crazy infrastructure needs. So you have two totally different backends, one generating AMP pages and one offering an JSON-based API for your Progressive Web App. But think for a second what AMP really is. It's not just a website. It's designed as an ultra-portable content unit. It's also a data format. The AMP team has asked themselves the logical next question, what if you could dramatically simplify back in complexity by ditching the additional JSON API and instead reusing AMP as a data format for our Progressive Web App. We started with a proof of concept many months ago and iterated on it for a while to see if this pattern actually works, rewriting many parts of AMP to make that reality. So how did we do it? Well, of course, one easy model would be to simply load AMP pages in frames. But iframes are slow, and now you need to recompile and re-initialize the AMP library, the AMP JavaScript library, over and over. Today's cutting edge web technology offers a better way for that. And it's called Shadow DOM. In the old world, our worldview was simple. One window, one instance of the AMP library and one document. But in that new world, there's one window, one instance of the AMP library, and multiple documents. So this results in super fast transitions between AMP documents as the library only needs to be compiled once. So you only got the one AMP library compiled once. The process looks like this. The progressive web have hijacked navigation clicks, then does an hijacked request to fetch the requested additional AMP page, and puts the content into a new shadow root, and tells the main AMP library, hey, I have a new document for you. Check it out. And it does that by calling attached shadow doc on the runtime, the runtime, which is what we call the AMP library. So even cooler, we have added a conditional CSS class on shadowed AMP documents so you can automatically hide stuff like headers in embedded mode. So the AMP shadow class does that. And shadow slots, which is coming pretty soon, allows you to insert advanced widgets and functionality into your pages that live in the shadow root in your PWA. And so of course, you can do that last step and the step here. So you can insert and remove things also manually, because it's really your XHR call. By just rexing the source of the AMP page, like I previously showed with the service worker sample. But the keys at the above is really easy for everyone, and the classes also makes it super, super simple. So here's something, finally, after amp up and amp down is like amp sideways, up down, whatever, Konami code, right? So time for an advanced pattern to wrap this pattern up. So we have a pretty good experience now. But if you're in the Progressive Web App, copy a link and share it on Twitter, that link will open the Progressive Web App directly, because you're not on an AMP page anymore. And for a new user who doesn't have a warmed up service worker pre-cache, it won't feel instant. So that problem is also a problem we can solve in the final step of our development journey. Instead of creating a separate URL space for the Progressive Web App. So for instance, pwa.youtermain.com, like we did before, we just reuse the existing AMP URLs to load the Progressive Web App on your site's origin. And so we're doing that by having the service worker simply intercept the navigation request. All we need to do for this is listen for that navigation request in the service worker. And then instead of serving a cached AMP page, we serve the cached PWA shell, which then does an XHR to fetch the requested AMP doc. This means that in just one request, your Progressive Web App will show up along with the requested content. So you got one AMP, one Progressive Web App, and one request. Now best of all, we now progressively enhance our AMP pages with our Progressive Web App. And during that, no matter what, your users will get a super fast experience regardless of AMP or PWA. For browsers that do not support service worker, they simply see AMP pages. And even here, if you think, well, I still want my Progressive Web App, even though it might not have all the bells and whistles, to work on browsers that don't support service worker, and we have a solution for that too. We have something we call fallback or rewriting that literally just landed this week in the latest Canary version, which is sort of our beta channel for AMP. And it means that if you arrive on an AMP page with a non-service worker browser, we will realize that in AMP. And rewrite all URLs, all outgoing URLs on your page by pattern matching based on a pattern that you can select to redirect to a fallback PWA URL. So you can have, for browsers that support it, you just use one URL space. But in browser that don't support it, we'll still go to the Progressive Web App. And we even load a hidden iFrame that warms up the browser cache. It's not as good as having a service worker, but it's still better than nothing. And so now we have, it's time for demos, but this is actually one demo that the AMP team has built. And it's a pretty cool React-based demo for you all to try out and get inspired. But I'm not going to go talk too much about it because I thought it'd be even cooler to show you a real-world example. In fact, the first real-world example that we know of. And that's Mike, who've done a heroic effort in the last weeks to get us to its current state. Please welcome David Bjorklund, lead engineer of Mike, to show you the new Progressive Web AMP experience a lesson learned on the way. Thank you. Thank you. Thank you. Hi, everyone. Can you hear me? Yes. Awesome. So let's go to the demo. Yeah. So I wanted to start with loading an article. So this is an AMP article. As you can see in the source code on the right side, we're using the AMP tags. So if you were to come from search, for example, this would be the instant experience. This is what a user sees when they come to this site for the first time. We've never been able to do it before. So let's go over here and navigate to the menu. So I don't know if you notice what happened here, but when we loaded the menu, we actually reloaded the page. Because we want to take you from our AMP article to our PWA as quick as possible. And in this case, since we've loaded the service worker in the background on the AMP page, it has loaded all the data that we need to show the PWA. And since we're sharing the URL space, the URL is still the same. So we're now in PWA. So I don't want to talk briefly about how we built this. So we set up to do a proof of concept. We gave ourselves two weeks, and we had three engineers that could work on this. And as part of the team, we knew of PWA. We've seen the videos, we read a couple of articles, but we didn't have any hands-on experience on doing PWA. But since we could reuse our existing AMP rendering pipeline unchanged, that really, like, jump-started our AMP journey. Like, it was just a few days into the work that we could, like, we could start working with the fun stuff. We could start working on the service worker. We could start working on all of these PWA features because we had already AMP stuff in place. So that means the event that we had time to work on performance improvements. So, like, we did what a lot of others have talked about today. Like, we made sure that our JavaScript bundle was as small as possible. But it also made us give us time to, like, experiment, to play around a little bit with Eurik's improvements. Like, the menu that I showed earlier where we do this, like, this reload. And it also gave us time to, like, really dig in and try to, like, learn as much as possible about the service worker. So we could, like, we could feel that we could come closer to something as a perfect cache. And, yeah, as I said earlier, it gave us time to implement WebPush. And, like, it didn't end up the time frame that we had, and with the resources we had, we never would have time to do any of this if it hadn't been because of the simplicity that AMP, that Ambedic AMP in PWA gave us. So I want to, when I did the slides, Paul asked me to, like, be honest with you and talk about the pain points. So I went through and I tried to do a list and I talked with my team and we talked about, like, what has this, how has this experience been? But, like, it was actually sweet. Like, it worked, it worked as advertised. Like, of course we had certain pain points to do in PWA, but, like, everyone, that's what we've been talking about for the last few days. When it comes to actually embedding the Ambedic AMP inside of the PWA, it just works as an advertisement. With that, Paul, I'd like to bring up Paul again so you can wrap up. All right. Thank you, David. So wrap up. Now there you got it. We successfully combined AMP with a progressive web app. And now the user always gets a fast experience, no matter what. Your site is progressively enhanced. You have less backend complexity because you just have one data source and profit from the building performance of AMP everywhere even in your progressive web app. And that really reduces the overall investment. Now, before I leave you, keep in mind that this is just one pattern to build sites and what works for everyone. You probably shouldn't build the next Air Horner or Gmail with it, but focus on sites that have a lot of leave nodes, individual sites with lots of static content. By all means, find out if that pattern is the right one for you and feel free to get in touch to discuss. So check out our React-based demo. Check out beta.mic.com to actually see a live experience. And also learn more about progressive web apps on developers.google.com. And of course, more about AMP on ampproject.org. And I really can't wait to see what you've built. Thank you.