 Okay. So, yes, I'm Paul. And I work in the deferral team, web deferral team at Google. But right now, my specific focus is on AMP. So I work with the AMP team on solving a lot of problems for the mobile web. Now, today's talk, and I said I don't have an intro slide, would have been a good idea, is not just about AMP but about AMP and PWA and how to combine it to work with both solutions. So first, why are we even building? Well, a couple of things. It's cross-platform, it's composable, it's indexed, out-of-versioned, easily deployed, secure, linkable, and really limitless, open for everyone to play. Some of the carriers that really make the web what it is and why I like it so much, still to this day. And before we jump into specific problems and solutions, what is the ideal user journey that we think the web should look like in 2016? So in this case, we have an example of a shop. And the first thing is you start with a search. Well, you find a search result. It's actually an AMP page. You click on a search result. Immediately, in an instant, it loads that search result page. Now you explore the category, you pick a favorite, and then going forward, you see, well, okay, it's unfortunately out of stock. However, there's a button to get a notification when it's in stock again. So you get notified when it's in stock. So then the application asks you for your permission to send you a push notification. And then finally, you stay up to date. Now going forward, at some point, you go on train, you lose the connection. But you continue exploring as it turns out, the app works completely offline, even though it's on the web. So even without exception, you get all the things you got before. Now at some point afterwards, a couple of days later maybe even, you get notified by the website, see, okay, my product is in stock again. You click on it, you can buy directly, you go to the card, add it to the card, you check out, and you pay directly with Android Pay or any other payment solution that you have on your phone. And also, you get signed in automatically because you signed in before. So there's no process of entering a password doing anything. So yeah, after that, one tap to pay, and I realized that this might not be a reality today in India, but we're working on it. So there are some complications in India. And then finally, because you like the app so much and you want to consume it further, you want to browse further, you add it to your home screen, you can access it as much as you want to, like a native app, and then you re-engage whenever you want to. So that to us is really the ideal user journey. Now, how we implement that journey is a completely different story. So why isn't everyone building this for the web? What are the problems that are holding us up? First, you got slow loading non-responsive content, especially, and that's kind of the bane of my existence, is the content shifting. I really hate that when you load an image, the image loads, and you jump around with a paragraph and you can't read anymore. And of course, what's the solution to this? Well, no megabyte size images, no render blogging apps, no 100K lines of JavaScript, and now you probably all, well, duh, I mean, I'm not dumb, right? I'm a developer and I know what to do, and I actually believe you. You probably know what to do. However, your manager doesn't care, because your manager has a job to do, and he is desperate because he wants to make more money because his site doesn't make enough money. So he's going to force you to add that new beacon on new analytics library, because it measures things differently than the other analytics library, and you need both on the site. It's super, super important for some reason. So you give in even though you know there's a better solution. And unfortunately, it wouldn't be all so bad if it wasn't the web. If you were in a native environment, in a restricted programming environment, you could probably force the beacons or the analytics scripts or something to restrain themselves and not cause any havoc on the site. But on the web, it's like giving your key to a hundred different strangers. What could go wrong? So that's a real big problem. And turns out, and this is really, really new data that we published just a few days ago. The consideration is actually pretty bad. The current situation, and I think this is a worldwide step on what we've measured on DoubleClick, was that a mobile webpage makes 214 different requests. The average low time is 19 seconds. 50% of that is ad related. And 77% of mobile sites take longer than 10 seconds to load, which is really unfortunate. Now, on the other hand, you also got missing device capabilities. And this is kind of obvious. For a long time, you couldn't have payments on the web, which is why the ad model is so overused. And because there really wasn't, there never was a technology built into the web that could monetize differently. Paywalls had to be built afterwards. And there's a lot of different versions of them. And actual monetization with credit cards or with banking was never part of the web in the first place. So that one is kind of an obvious one. We just need some more capabilities to create re-engagement to do other things. So solution. Part one to the solution is AMP. At least we think it's a solution for the problem. Now, what does AMP do in a nutshell? It allows you to build really high performance web pages. And it gives you a rich catalog of web components, pre-built library components that you can embed into your site. And it's basically HTML. So it's not just a completely new standard. We didn't reinvent the wheel. We just added web components where they make sense. Now, you would say, probably, okay, why did we replace image with AMP image? I'm going to go to the reason very soon. There's a very good reason, believe me. Now, the publishing flow for AMP pages, usually goes, you create in your CMS or you create it manually. You might or might not create two versions of the same page. One is your full version of the page. And the other version is the AMP HTML page. They're linked with a canonical tag. And then they get cached. Because that's one of the biggest amazing features of AMP is that it's a container format. So it allows the publisher, it allows the integrated platform that loads the page to say, okay, I can actually load this page standalone. And there's probably no dependencies that will mess it up. So a cache on top of it can cache the entire page and then deliver it much quicker to any subpoena. For instance, in this case, Google or Twitter are pinches. And then finally it gets consumed. There's a strong ecosystem already. A lot of members are joining soon. Bing just joined. WordPress is supportive. Feedly now redirects traffic to AMP. Those are just one of the new ones. And the Google campus is that support AMP. Because I work at Google, I know some of this better than the other ones. So first of all, you get, this is what we started with. The top store is Carousel, where we integrate AMP. Rich cards and search, news and weather app. And soon, and this is kind of important. Blue links and search. Those are just the organic search results that you get in search. And if we find out that there's an AMP page equivalent of that page or the page itself is AMP, we will open it in a viewer almost instantly because it's preloaded. So AMP pages are really just web pages. It's HTML plus CSS. There's no one-off JavaScript. It's that custom elements and sandbox AMP iframes that contain, can contain everything. And then in addition to that, there's the AMP open source library, which I usually talk about, the JavaScript library. The same everywhere, of course. It's highly cacheable. There's just one version of it. So far at least. And it defines behaviors for custom elements, manages the rendering, manages the loading pipeline to optimize performance. I say, wait, okay, no JavaScript. Where's JS foo after all? That kind of makes me sad. So yes, we had to take some of the toys away in order to make pages really, really fast and get them into a controlled environment. So three sources of speed in AMP. One is the format. Second one is caching. The third is pre-rendering. So in the format, sure, you have an average mobile site. We just looked at the numbers and what that means. Of course, you can hand tune your site. And if you hand tune your site and you're the only one deciding what comes to that site, you can do a very good job. In fact, you can do a better job than AMP, most likely. And obviously, has a lot of the performance benefits embedded already. But it's a generic solution that can always be surpassed by doing something hand crafted. But the point here is that we can do this at scale. We can optimize a lot of pages at scale even if developers don't really know all of those techniques. And so you get a single HTTP request to fetch an entire document and then fonts, which is an exception. CSS is in line in AMP, a maximum of 50 kilobytes that we enforce in the validation process. There's only GPU-optimizable animations. Minimal-style recalculations because we control it everything. So AMP triggers only two style recalculations during a typical page load. And all scripts are asynchronous. So this is the main AMP library script. Instead of a synchronous load, you get an asynchronous load. And this is one of the most important things that most people don't know about or discount is the static layout engine that we've built. So each element has a static proportion. So even before, here we go, yes, so even before we know about what the assets are actually are, even before we get the images and the videos and everything else, we don't have a situation where extended component downloads block page layout or assets block page layout. So in this case, just going back quickly, we can lay out the entire page without knowing any of the assets because the sizes are all constrained. So third-party JavaScript is only allowed in Sandbox for iframes. So you can still use iframes to do whatever you want to, but they get deprioritized, so the content gets prioritized all the time. So how does the resource prioritization look like? Well, we optimize the resources in the viewport and we can only do that because we can statically layout the page as soon as we have a document, even without any assets. This is why the pre-rendering works so well, because we can pre-render the viewports and not just the whole pages. Now, second one is caching. And again, caching works because the AMP format is validated and it's very clear that probably nothing bad will happen if you load an AMP page. Now, the AMP cache that we offer is built on Google infrastructure, so it uses all the edge servers that Google has. It's free, which is a nice benefit and it's used by Google and a lot of other properties, but we are opening up the deck of how to build an AMP cache to other companies, so it's very possible that we'll see other companies do the same. And speed source number three is pre-rendering. So pre-rendering really can make loading instant. Again, we pre-render just above the fold and that's why clicking on an AMP page feels so quick, because we pre-load not just the one page, we pre-load a couple of pages that we think you could click, because it's so cheap to pre-load them. So free source of speed, format, caching, and pre-rendering. Now, we solved the first problem. We now don't have slow loading coming anymore. It's very responsive and the counter doesn't shift anymore because of the static layout engine, but we haven't solved the device capabilities problem. For the device capabilities problem, we go to part two. And in this case, if you look at a native in comparison to web access, you have, on one hand, capability, and you have on the other hand, reach. So the web is actually extremely good at reach, as you all know. Native is very good at capability, naturally, because they don't have to standardize anything. They can operate on a much faster scale and are much closer to the actual hardware. However, what we wanted to achieve when we started building progressive web apps, or created a term, progressive web apps, is sort of a hybrid that gets us from the reach to extended capabilities as well. So how do we get there? The first reliability, super important. Slides need to be reliable at all times. Portion notifications, home screen access, and very new simple sign in and one type check out. So offline, right, no one likes that one. So bad offline or source. When you're going to use this home screen, there's really no excuse to show that dinosaur. So you really should always be available. What we do for that is service worker. So service worker is a sort of a proxy that is almost like a web server on the client. And that intercepts requests if you want it to. And can cache any kind of assets that you give it to. Much more flexible than app cache has ever been. And allows you to do to go completely offline and actually pre-cache stuff like an application cell. So not only does it offer you basic offline capability, but you can cache the shell of an application almost like all native apps do. And then the shell loads instantly on repeat visits. Dynamic content gets them pulled in to shell. Then we have push notifications. They are built on service workers. So you get a push subscription end point and the service worker reacts on push and shows an application. Here we go. And finally, you got a notification on the actual device. How does it work? You get set up and you check if the user is subscribed. You wait until a good time. You ask the user to subscribe. You send the subscription. You save the subscription. And if you want to send a message, you generate a message. Send to end point. Send to browser. And then the browser receives it. If you receive messages, I push a rise from somewhere in the service worker. The service worker boots up if it's not running anymore on the device. And then messages are handled. And the notification is shown. So the key here, going one back, the key here is that notifications can happen even without the browser window open like with any other native app because the service worker can keep running in the background. Now, home screen access. This again is super important if you want to engage with the users. The home screen access you can do by using a web manifest. I'm going to show you a quick example of how it looks like later. But basically you get a prompt. You can add it to home screen. And that's much easier than before where you have to go into the Chrome settings or other browser settings and find the menu entry first to add it to the home screen. So what are the latest prompts we're solving? We're first signing in as a huge pain point for users. 54% of users were quit before doing yet another sign up. And 92% of users would give up if they don't remember username or password. So that's why we built the credential manager API. And that one allows you to save the info for easy access later. And first time users get prompt to save that into smart log. And then returning users can actually be signed in automatically without having to ever type a password or even see the login form in the best case. And then the next problem is a checkout problem. If you have too many steps on mobile, fill out forms to enter credit card details, et cetera, it's really bad conversion. So how do we fix this problem? Payment request API. I already talked about it briefly. But essentially, you get a, in the best case, a one click scenario of enabling payments on phones and on the web hopefully as well. So which to choose? You want to do AMP? You want to go really fast? Well, that works for many companies like the Washington Post. They get a better user experience with AMP. The load times increased dramatically over 88% improvement. And the reader loyalty and retention improves as well, which is really interesting. So AMP works really well for the Washington Post. On the other hand, housing.com, where we have two talks tomorrow, which I'm going to check out and I'm really looking forward to, reported that with a PWA, they got a 38 increase in conversions and 30% increase in page load performance. So yeah, on the one hand, you get instant delivery, optimized discovery, and unfortunately no user scripts. And almost only static content. It's really optimized for static content. But then on the other hand, you got progressive web apps and they give you installability, app-like features. However, they're slower to deliver, especially on the first load, and they're not easily embedded. So you can't build a viewing experience in a platform as easily. So instant first load or native like app? Well, I say both. Why not both? So how do we go from AMP to progressive web app? Well, level one is to start with an AMP experience because you really want to get content to use this instantly. And that's ideally the most important thing for you. Because if that's not happening, well, you can give up immediately. So you want to get an instant first impression to the user. Well, you have a lot of text to try out to do that. Now, first of all, you need to determine if you want to do just one AMP page or if you want to do a paired approach, where you have the full site or another site. You can then validate the page. If you inserted some components and not sure if you did it the right way, you validate that page. Now, the validation also is done by the AMP cache. So chances are, if your pages don't validate, they will never appear on any of the third-party platforms that support AMP. Now, this is a feature, not a bug. The feature being that we can be really sure that AMP pages are all conformant and fast and doesn't do anything bad. So you can do it right in Chrome DevTools if you want to. You can use the web interface on Validator.ampproject.org or you can even use a browser extension. And if you're hardcore enough, you can do it on the comment line and optimize it for a lot of pages. So how about AMP for desktop? Well, I think we did kind of a mistake, to be honest, when we named AMP Accelerated Mobile Pages because the mobile in it really doesn't mean anything. I mean, it means that you would probably get the best benefit on mobile because you have high latency situations, et cetera. But you can absolutely use it for desktop and, in my opinion, you should. There's no reason why not. You can build responsive design all the way. So in this case, you can, for instance, use a layout property in AMP to, and this works on any AMP components to set the size to fix responsive, fix tight or fill. And responsive is really nice because it has a fixed aspect ratio but resizes to its parent with something that not trivial to do in CSS and requires some hacks. And then you can use SOSat in every browser and even browsers that don't support them because we probably fit it. So you can do really nice art direction and use different images for different browsers in different environments. Finally, Element Media Crease is another very interesting idea where instead of doing a CSS style sheet Media Crease to disable things, you can do it on a per component basis, on a per element basis. You can say, only show this element in a certain restricted environment, on a certain resolution. So you can easily switch on and off elements on the slide. So let's get working. So what we want, okay, first of all, this is the AMP homepage. And I have the sidebar here. And the sidebar has a language picket. So, and then if you click on those things, you get sort of a accordion effect. So this is what I wanted to build. AMP sidebar to the rescue. I found the component by searching for docs. Sidebar does exactly that. It's a sidebar. The cool thing is that we have an event model that allows you, even without JavaScript, to say, if you click that button, open that sidebar. And so when you click on a hamburger, it opens the sidebar and you put anything you want in that sidebar. Sidebar works on mobile. And what about the drop-down? Well, there's no AMP drop-down. So what do we do? Well, there's AMP accordion. But I don't really want to build an accordion, do I? Well, if I look at AMP accordion on ampbyexample.com, which is a nice site that one of our team members built, you can see that, sure, you can make it style like an accordion. But in fact, you can be a little bit hacky and also slide it differently and just have one entry. And basically, it kind of looks like a drop-down. And if I change the markup and actually give it a height, a fixed height, and no overflow, I can make it behave exactly like a drop-down. And that's what I did. So now you get the drop-down. And really, it's just an accordion. Sometimes you have to be creative to work around something. And of course, sometimes also makes sense to add a new component. If you discover something that really doesn't work, then we should add a new component. So this is great. But how about this menu? On my own website, which is completely AMP, I wanted a menu that looks completely different. So what I did here is I went a little bit crazy, and I created a label, which is the hamburger icon. And then I created an input with a type checkbox that is hidden and controlled by the label. So if I click the label, the checkbox toggles. And the element right next to it is the menu. So in CSS, I then have an adjacent selector to toggle the menu based on the actual checkbox. And this works pretty nicely without doing any JavaScript. So you can toggle it by clicking. Optimizations will only include the AMP scripts needed for the pages tags, if you can. Otherwise, you end up with a huge bunch of stuff. And only load the CSS you need for a given page. And again, if you can, I have to say I was lazy so far on the AMP page itself. I actually don't do this. And I use the same CSS over and over. This is not good practice. So make sure that you try that. Those are just a few examples of how to work with AMP, but more can be found on ampbyexample.com. Now, level two. Now we have a pretty decent AMP page, probably. Level two is Accelerate Subsequent Loads with Service Worker. And yes, you can use Service Worker on an AMP page. So the first way to do it is to use a library like SW Precache, which is the easiest way to do it without Service Worker and without Service Worker experience. So SW Precache, you scan directories, cache all files you find, cache files within the URL pattern. This is to cache the actual AMP project library. And then you remove a directory string. And that basically is all you have to do to generate a working Service Worker that caches all of those resources and makes them available offline. Now on the AMP side of things, in general, you have to use JavaScript to install the Service Worker. But in AMP, we have a tag called amp-install-service-worker. And you can then load and actually fetch that Service Worker on the AMP page without using any user-authored JavaScript. Now, the cool thing about this, that this even works in a cache scenario. In the cache scenario, you're not on your own origin. And yet, we will establish an iframe and fetch the Service Worker and initialize as a Service Worker on your own origin. It means that if you click the second time to another page from that cached version of the page that you see on a property like Google, you already go to the Service Worker one. So the other thing is that in some cases, we wait a while until we install the Service Worker. This is just a gotcha. Because we don't want accidental Service Worker installs. Now, if we take a look at this, we can see, OK, Service Worker installed. And everything got cached. All right. And now, we can go offline. And it will work. So click Offline Box, Reload, and the page is there, except the YouTube video, of course, because that one, we can't really cache offline. Everything else works. So that's just one solution without any action on our part, without any JavaScript. But we are JavaScript engineers, so let's get real. So if you want to do it without a library, you install the Service Worker in the Service Worker file. This is the install part. I like skip waiting because it says, don't wait until the old Service Worker doesn't run anymore. I want to update immediately. And then I open my cache and a couple of resources that I need for sure. I would put more in there, of course. This is just an example. But you cache everything that no, you need in any moment if you want to go offline. And then you activate the Service Worker. This again has a step that says, OK, even though I might be completely new and the page has already an older version of the Service Worker, claim all clients currently connected to the Service Worker immediately. And number three, intercept requests. So we do that by adding a fetch event. That says, every time a resource is fetched, do something. Now in this case, we say, OK, respond with something else than the actual normal browser fetch. So as soon as we call this line, you have to deliver something or nothing will appear. In this case, we open our cache. We see there's a cached version of the page. So we match the request. Then look at the response. And we will fetch the promise. We have a fetch promise in here that we're using just a bit. And down here, we return directly if we have the data and the cache, or we use the fetch promise. And the fetch promise fetches a new network version of the same page in any case. So it does that anyway. And that means that we will serve the current version all the time, and then get the next version in the background, and then on the subsequent load, get the updated version. So this is a very basic example how to do an offline strategy with service worker and cached pages. And of course, this doesn't only mean you need this for offline, but it also means that it will dramatically speed up every subsequent click. Now level three, and this whole example will become important in the next level, level three is add a web manifest to trigger add to home screen banner. So we talked about web manifest before. Again, all you do is, again in the AMP page if you want to, add the manifest. The manifest has a couple of properties. The most important one's being display, which hides the browser bar, the browser L bar, theme color, background color, and especially the icons are very, very important. Otherwise, if you don't have icons at a certain size, I think 144, then the add to home screen banner will never trigger. So you need that. And the cool thing is that you can inspect it in DevTools. If you open DevTools and go to the application panel and click on manifest, you see what the browser thinks your manifest looks like. So you can inspect any errors on fly. So add to home screen action, in this case with flip cart. Again, how does it look like? You get the prompt, the add to home screen. It's added to your home screen. And if you launch it, you get a nice preloader and jump right in. So what's cool about this is that you just build a PWA. Even though you are still an AMP, and this was still an AMP page, you just build a complete PWA without writing any JavaScript in the client. And I think that's pretty cool. So we have the first step solved. We have a very fast first experience. And we have an experience that offline and can be installed to the browser. But now it gets interesting. Level four is enhancing your AMP with the service worker. So in here, it's important to say that the cache that you can store stuff in isn't unlimited. So AMP forces inlining of CSS, as I just showed you. And a typical page head on AMP.org is about 43 kilobyte, which is significant. Because if it's 100 docs, which is approximately the amount of pages that we currently have on the AMP project or site, it's about 4.3 megabytes of additional clutter that I cache with every request I cache, with every document I cache. So this would be a very common issue. But what if we could only cache the body and merge with the head on request in the service worker? And we do write exactly that. So we create a new template called docs blank. This is just the head with the actual CSS in there. In the service worker, we write a function that is called get template. It fetches the actual template from the cache. It gets a text response, because we need it later on. And stores it in a variable if it's already done that once. Now in the fetch request that we saw earlier, we expanded a little. So in the fetch request, what you do now is I grade out the lines that we already did before. What you do now is you clone a network response, because then we can manipulate it further. If it's a document, we get the text from the network response, which is the body of the page. And then we match just the body. And you should never do this at home. Please don't use regex for this. It's bad. Ideally use HTML comment or something to do this. But we match the body. We then save the filter response, so the actual body portion of that page, in the cache instead. And by constructing a new response, putting in the cache else, if it's not the argument, we put in the cache directly. And finally, this is very similar to what we did before. If there's a response already, then we see the document. We then create a complete response, otherwise deliver the already existing response if we don't have a cached one, and otherwise go into the fetch promise. So how do we stitch it back together in the create complete response function? We get the template, which is just the text, the part of the page that has all the CSS, and we get the body and stitch it back together and respond to the browser. And this is what happens. By having the exact same result for the client, we get a previous cache size and new cache size that is much, much smaller than before, which is a nice optimization to do. So again, we did something on the AMP page without actually doing any user author JavaScript in the client that helps us dramatically. But now I want to go one step further. I feel kind of nostalgic. So I think one of the saddest parts of my page is that I can't use any of the 90s JavaScript that I love. So I went to this page called Rainbow Arc Scripts. And I found this amazing mouse cursor that I think would be very helpful for all of my AMP pages. And I just can't have it in AMP. And I know why. I should probably file a bug request. So what can we do? Well, I just showed you this, where we stitch together template and the other one. Well, no JavaScript. OK, what do I do? Well, how about I get some random stuff in between those two files, random stuff that AMP doesn't like? How about that? Well, let's do exactly that. What happens? Here we go. We get a funny, animating background. We get our amazing clock, which is our mouse cursor. And we still have an AMP page. And it still uses the AMP library. So we now hijacked our own page and inserted JavaScript into it and done whatever we want to. And the crazy part about this is that usually you would think, well, the AMP cache will complain about it. And well, no, my AMP's will not appear on Google. And yes, whatever I done, that's really bad. However, the cool thing here is that the AMP cache doesn't know about your service worker. So the Google AMP cache will see the normal AMP page and will cache it just regularly and think it's valid. But then consumers will see the AMP page on first click and the extended AMP page on subsequent clicks. So you can easily amend your page with whatever you need, whatever you want on your page and whatever you think is right for your users, going forward after the first click. And now this is where level five becomes extremely important. And level five is kind of alpha. It's the boss level, I would say. And it's completely rerouting the AMP and the actual URL that the user went to, to an app-like experience, to a progressive web app. So how would this look like? In the case of one in post, for instance, they lead you to an AMP page, but then they use AMP and source service worker, and then they reroute every subsequent click directly to a PWA, but then loads that page you clicked on in a viewer. So they do that in a separate URL space. It's not exactly what I'm envisioning, but it is a very fair technique. There's a couple of techniques that work with that concept. But what I'm saying is, and this is kind of what we're thinking, is the service worker hijacks all navigation. The service worker then serves a PWA shell. The PWA shell initializes a shadow DOM-based AMP viewer, and the originally requested AMP document is fetched via XHR, and then subsequent navigation uses history, push state, and XHR to navigate within the AMP viewer only. That still means you only have one URL, one URL space, and it's really much less complexly that you would have in a other scenario where you have to implement everything again, because you already have your AMP pages. You have all your leaf nodes, all your documents are already there, are already nicely styled. So instead of using JSON and then reconstructing everything complicatedly in the PWA, you can use that technique and embed it in the viewer and strip out the head automatically in the service worker. So I don't have a very fancy demo for you yet on the AMP viewer approach. We're still actively working on it, but there is a demo. And if you want to check it out, in the AMP project source code itself in mHML, there's an example called PWA that does precisely this, that initializes an AMP viewer with shadow DOM. And one of the cool ideas that we had recently is, because we've got the question, what happens on platform steps don't support service worker yet? They will always get to see the AMP page in the scenario. Well, one of our ideas is to then have the AMP library detect that a client doesn't support service worker and then rewrite all the URLs on the page dynamically to an URL space that you define as a fallback. That's another solution to always get to the PWA in any case. So a few. There's a lot of stuff, five steps to get from AMP to PWA. If you want to learn more, and I hope you do, go to mproject.org slash docs and you see my face again and a lot of other good stuff. And then go to developers.google.com slash web to learn about general web techniques and also what we do with progressive web apps. And this is a really, really cool course by my buddy Jake, who is also part of my team. And he created this offline web applications course that helps you to really find out how service worker works in detail. I mean, I skimmed over it, but this is actually very helpful. And finally, YouTube. We do a lot of stuff there. There's a new series coming up soon about AMP. And we also have a Slack where you can always ask us questions, but of course, you can ask me questions here. And finally, some Twitter accounts. And that's it. Thank you, playing judge. And I think we have about four minutes if anyone has questions. So are you suggesting that the first point, load performance can be moved from a service and an app to an AMP project-based implementation? And the rest is always PWA-based thing? So are you suggesting that instead of going for a serotonin approach, go for an AMP approach for the first load performance? Yes. Yeah, that would be my recommendation. Because you will never get the same speed with a PWA. And the reason is not that the PWA, theoretically, cannot have the same techniques. I mean, it could also be a small and using the same characteristics. The reason is that it doesn't have the same static layouting system out of the box. So the platform that embeds AMP is not able to preload the first viewport. And another thing is with a serotonin approach, the limitation you told is that the service is only at one place. But with AMP, you have a distributed network of cache, like a CDM. So is that the only advantage, or do you have any more advantages than that? I'm not sure I understand the question. So if I go to a serotonin approach without using AMP, still my content is coming, the first load of a website content is coming from one server situated in one part of the world. But with AMP, I'm getting a distributed cache. It's like a CDN effect for my original web content. So this is one very big advantage that I get with AMP. So are there any more things that I get with AMP? Yeah, I think so. I think that's a good advantage. I mean, if I understand your question correctly, the fact that you're going into the AMP cache on the first request gives you a lot less load balancing to do on your server. So it's a lot of traffic you save. And you can still use analytics to track those clicks if you want to. Hi. So actually, here on the back. Oh, over there, yes. Yeah. So initially, you said that the pre-render is based on user behavior that you have earlier, right? Like whatever your pre-render is actually based on what the user actually clicks, you have some behavioral patterns for that, right? What amount of the page is actually pre-rendered? Like say, if I have in the navigation, I have 10 different tabs which actually load 10 different pages altogether, like a e-commerce website. How much of it will I pre-render if I don't have the user-behavioral pattern or something like that? So the pre-rendering only refers to the current leaf page. So by pre-rendering, I mean that not many. So it's only the current page that gets pre-rendered. So what it means is, let's say you do a Google search for something like flower. And OK, that's not really a good news term, but I don't know, Obama, right? And then you get 10 different AMP pages as recommendations to click on. Then in most cases, it would be not really doable to pre-render and pre-cache all of those 10 pages that are coming from different origins. But because of AMP can cache just the first viewport, it does that. So it doesn't cache subsequent navigation. If that makes sense, it only caches the first navigation. Hey, Paul, I'm here. Great talk back there. I have a few questions actually. Like you said, as far as I understand, like service worker caches the pages hasn't been visited, right? So if I'm about to create an application which has things which are loading all the time, like automatic feeds or news sites or blog feed, for example. So how is PWA really useful in that situation? How is PWA useful in that situation? Because caching will not help in that, right? Well, I mean sure, you mean if you have a very interactive page that requires a lot of interactive data, is that the question? Well, the service worker is still very effective if you use it the right way because you can cache the entire app shell. So every UI element of the page you can cache. Of course, you can't cache the data, but at least you can improve the perceived performance of the loading experience much, much better. Because on most native apps, you see, some of them are actually even slower than web apps, but you see the actual layout of the user experience immediately and then content dribbles in. This is not really improving the time it takes to get the data on screen, right? However, it will feel much faster. OK. And one more thing, is there any specific change that we have to do in the UI architecture for rendering this or normal the way we do this? Sorry, what's special? For using the service workers or PWA, like do we have to bring in any new architectural changes in our application? No, I mean the only requirement is HTTPS. OK. So your page has to be in HTTPS. Again, you said something about the smart locks, right? Like that saves the username and password of the user as in when he typed in. So you understand what I'm saying? So smart lock. Yeah, smart lock is a Google feature that is basically a password manager. And it works in combination with the credential manager. So the credential manager can also work on its own. So in Mozilla, for instance, they would use a different password manager. But yeah, it's built on top of that. So I wanted to ask that, like all the websites from which people visit links, Google, Facebook, and Twitter are three of them. So Google has started with AMP. And then later on, Twitter and Facebook has also added the instant article standard. So isn't this breaking down the standards a lot of the web? Because if you are a website like Washington Post, you want it to be instantly available on Facebook as well, on Google as well. That means you have to write a lot of custom tags, which are not an HTML standard or anything. Yeah, so a good question. I think the, I'm running out of time, but I'm going to answer this quickly. I think the answer here is that those on the public site they're very similar, so different endpoints. So usually if you want to generate for all of those endpoints, you have a CMS that will export for multiple endpoints. However, the approaches are very different. One is living and hosted in a relatively closed ecosystem. And the other one is really just a JavaScript library and a validation system that is very open web-friendly, in our opinion, and can be embedded anywhere on the web. It's really just web pages with a little bit special magic on top. So our hope is that AMP will just be used as a library going forward and hopefully work. So for instance, in my blog, there's no two versions of the page. Because I don't need any JavaScript on the page. It's a blog. So I just use AMP as a library, and that's it. So it's all using AMP. With infant articles, I couldn't do that. So yeah, that's my take on it. Hi. So I want to ask about the service worker notifications. So in service worker, we have been using service worker notification for almost six, seven months now. There is this certain problem we have been facing and we couldn't find the solution. In service worker notification, there is a callback that you register on push. So in that callback, I get only subscription ID of the user, correct? And based on that, I make an API call to fetch the data from my server. Basic notification system, that's how it works. Now imagine my website hosts two kinds of products. Let's say we sell hotels and we sell flights. A person came to my website and registered a notification. And let's say he registered the notification from the flights product page. Now I want to, because I have a subscription ID in my server, I would want to send a hotel-based notification also. But I cannot context switch it because I only have one parameter, that is subscription ID. So is there a worker on to it? Maybe I can register two service workers to my website at the same time. Maybe, let's go. I don't know the specifics of the push notification site. However, people are working on a way to add multiple service workers on the page. Yes. So this is coming. We'll be able to add multiple service workers to a page. One of the interesting techniques here is foreign fetch, which you can Google. It's called foreign fetch. It allows you to have a service worker that controls other pages that are not his own. And there are also ways to install two service workers on the same page, as I believe, going forward. So I sadly don't have a perfect answer for you, as I don't know the specifics of push notifications. But yeah, I hope it works. All right. Thanks again. And come meet me afterwards.