Optimize your hosted AMP pages
This guide provides tips and guidance for webmasters on how to optimize their hosted AMP websites.
Isn't AMP fast by default?
The AMP runtime is optimized for speed and if your AMP pages are served by an AMP cache, they are fully optimized and offer the highest loading performance. For example, if your users are coming to your AMP pages from Google Search on mobile, by default the pages are served by an AMP cache.
However, AMP pages are not always served from an AMP cache. A website may decide to show AMP pages from their own servers for other traffic sources. The most frequent use case are sites built completely in AMP, such as axios.com, where users go straight to the site. Another traffic source is Twitter, which started linking to AMP pages instead of delivering the standard mobile version. This means that if a user clicks a link in one of Twitter's mobile apps, the link goes to the AMP version of your page on your own origin (if one is available).
As a consequence, you can't always be sure that your AMP pages are only served from an AMP cache. For these cases, where you are serving AMP pages from your own servers, it is important to make sure that your AMP pages offer the optimal loading performance.
AMP pages load fast by default, but there are some additional performance optimizations you can implement to help the browser load AMP pages even faster. This guide describes a few optimizations you should consider when publishing AMP pages. However, before you start reading this guide, make sure that you've already covered all the basic web performance best practices. In particular, image optimization has a big impact on loading performance.
For example, by applying the following optimization techniques:
- Optimized AMP runtime loading
- Preloaded hero image (the image size/encoding itself has not been changed)
- Optimizes custom fonts (in this case, Google fonts)
If you want to skip the details, use the AMP Page Experience Guide to check your AMP pages for possible performance optimizations.
If you're publishing an AMP page, you should use an AMP Optimizer. AMP Optimizers let you serve optimized AMP pages from your own backend which includes server-side rendering AMP layouts. AMP Optimizer also automatically performs many other optimizations described in this document.
AMP HTML uses its own image element:
amp-img has many advantages over the traditional HTML
img tag, one disadvantage is that the AMP runtime must be loaded before the image download can start. For some images, such as hero images for a product page, it's critical that the images load as quickly as possible. In these cases, annotate images using the attribute
<amp-img src="hero.jpg" data-hero ...>
This allows AMP Caches and AMP Optimizers to server-side render the
img resulting in much faster load times. Another best practice is to preload the image to ensure that the browser starts downloading the image as soon as possible.
<head> <link rel="preload" href="/images/elephants.png" as="image"> </head> <body> ... <amp-img width="404" height="720" layout="responsive" src="/images/elephants.png" alt="..." > </amp-img> </body>
But what if your responsive layout requires different hero images depending on the screen width? For example, a wide image for desktop and a narrow image for mobile like this:
<amp-img width="404" height="720" alt="..." layout="responsive" src="/images/elephants_narrow.png" media="(max-width: 415px)"> </amp-img> <amp-img height="720" alt="..." layout="fixed-height" src="/images/elephants_wide.jpg" media="(min-width: 416px)"> </amp-img>
The good thing is that
link rel=preload also supports media queries. So we can use the same media queries in our preload statements, like this:
<link rel="preload" as="image" href="/images/elephants_narrow.png" media="(max-width: 415px)"> <link rel="preload" as="image" href="/images/elephants_wide.jpg" media="(min-width: 416px)">
By the way, the same approach works for
amp-video poster images:
<link rel="preload" href="/images/poster.jpg" as="image"> ... <amp-video width="480" height="270" src="elephant.mp4" poster="/images/poster.jpg" layout="responsive"> ... </amp-video>
Just make sure to place the preload statements after the viewport declaration because the browser needs the viewport dimensions to determine the screen width:
<meta name="viewport" content="width=device-width"> ... <link rel="preload" media="(max-width: 415px)" ...>
Consider using a service worker
Now that all major browsers support service workers, it's a good idea to evaluate whether it makes sense to add a service worker to your site.
There are two different architectural patterns that we know will work for reliably fast navigations:
- For single-page applications: the App Shell model (in the AMP context referred to as AMP-in-PWA). This pattern requires a service worker to upgrade an AMP document to the app-shell-based PWA experience.
- For multi-page-applications: streaming composite resources. A service worker caches the static header and footer and uses streaming to instantly return a cached, partial response while loading the content.
If neither of these patterns is used and it's not possible to cache the whole site (which only is reasonable for very small sites), a service worker might have a negative performance impact. The best thing in this case is to not use a service worker.
However, if you want your website to be installable from the home screen, or want to offer an offline experience, you'll have to use a service worker. In this case, it's important to use navigation preload to mitigate the potential slowdown (Note: Currently, navigation preload is only supported in Chrome).
If your AMP website uses a service worker, here are some best practices:
- Pre-cache the AMP runtime and extensions (e.g.
- Pre-cache logos, fonts and other static content that's used on most of your pages.
- Serve logos, fonts and images by using a cache-first strategy.
- Serve the AMP runtime and extensions by using a stale-while-revalidate strategy.
- When using a network-first strategy for navigation requests, make sure to enable navigation preload.
If you're looking for a way to get started with a service worker in your AMP site, check out this sample that provides a service worker that implements all these best practices.
Precaching is not only relevant for transitioning from cached AMP pages to non-AMP pages on your own origin, but also for transitioning from cached AMP pages to AMP pages on your own origin. The reason is that the AMP cache re-writes the AMP runtime URLs from the evergreen URL to the latest released version, for example:
The consequence is that an AMP page served from your own origin does not benefit from browser caching and in this case has to download the (unversioned) AMP runtime again. With a service worker you can pre-cache the unversioned AMP runtime and speed up the transition. To learn more about why the AMP cache versions AMP runtime URLs, read this document.
With AMP there are a few things that you can do to optimize your font loading (most of them are actually not specific to AMP):
- If possible, use font-display: optional: This will only use the font if it's already in the cache, and falls back to the system font if your custom font has not been loaded yet.
- Optimize your web fonts (for example, serve custom fonts using WOFF2).
Preload custom fonts:
<link rel="preload" as="font" href="/bundles/app/fonts/helveticaneue-roman-webfont.woff2" >
If you are using Google fonts, or any other font provider with unknown font URLs, preconnect the respective font server:
<link rel="preconnect dns-prefetch" href="https://fonts.gstatic.com/" crossorigin>
Last but not least, try to minimize the number of custom fonts that you use on your page. If you can, use the system fonts instead of custom fonts because system fonts make your website match the user's operating system, and it helps to avoid loading more resources.
Of course, all the basics of web performance optimizations also apply to AMP pages:
Written by @sebastianbenz