Accelerated Mobile Pages: Under the Hood

AMP: Making the web great again

Since launching in October 2015, Google's Accelerated Mobile Pages (AMP) has quickly been building up momentum, with many of the major news publishers now on board.

AMP is an approach for making content-based websites fast to load, typically less than a second, and for many AMP-powered pages, almost instantly.

AMP can be regarded as similar in performance to Facebook Instant Articles, though with the important distinction of allowing publishers implementing AMP to control the publishing of their own content, unlike Facebook Instant Articles.

AMP is open-source, and the AMP team have been working with many of the third-party providers typically found on content sites (i.e. advertising, analytics, video etc) to ensure that third-party content loads fast on pages that employ the AMP approach.

For this post, we'll assume that you have a general understanding of how AMP works; if you haven't yet seen AMP in action, check the video on the AMP project site, the animated gif below, or see the real thing in action (you'll need to view this link on a mobile device, or in a mobile-sized viewport in dev tools).

We need Discipline

For web developers, AMP can be thought of as a way of enforcing discipline for good practice in making sites fast to load.

If you're a web developer, you can probably empathise with the image below.

Familiar with this?

Source has a great article providing reactions from web developers in the online news space, which includes some interesting allusions to the problems of guaranteeing good performance (in terms of speed) of news websites (my italics).

“I’m not optimistic that there is a business conversation around performance. I think we talk about a lot, as journalists, because we’re plugged into the trends and we love talking about ourselves. But I’m not convinced that news management is paying attention, or if they’re willing to make it a priority. I still have a lot of conversations where speed gets lip service, but we still cut “just this one” corner for business benefit X. Cut enough corners, and eventually you’re right back where you started.

Like so many things that we think are technical problems, these are actually questions of political will and support. If AMP succeeds at all ... it’ll be because its hardline stance on performance and third-party code can provide arguments for that leadership to advance.”

https://source.opennews.org/en-US/articles/what-amp-maybe-means-news-developers/

Importantly, AMP enforces discipline in two respects.

Firstly, development teams implementing AMP sites have to work according to the restrictions that AMP specifies. We'll look at those shortly, but suffice to say that AMP limits the options for teams to make make decisions that adversely affect performance, and provides an easy way to implement many of the measures that should be considered good practice when looking to make fast loading websites.

“AMP is basically web performance best practices dressed up as a file format.

That’s a very clever solution to what is, at heart, a cultural problem: when management (in one form or another) comes to the CMS team at a news organization and asks to add more junk to the site, saying “we can’t do that because AMP” is a much more powerful argument than trying to explain why a pop-over “Like us on Facebook!” modal is driving our readers to drink.”

https://source.opennews.org/en-US/articles/what-amp-maybe-means-news-developers/

Secondly, AMP enforces discipline regarding the performance of third-party code and content; development teams trying to produce fast websites are often hamstrung because of their lack of control over the performance of third-party code and content that the business mandates for inclusion in their pages. Lack-lustre performance from online advertisers, analytics providers, and video providers can often significantly contribute to the less than stellar loading peformance of many web pages, and can be at least partly blamed for the rise in interest in ad-blockers.

The AMP project have been working with many of the leading third-party providers to get them to serve their content via AMP-friendly mechanisms, and these third-party providers include the big names such as Adobe, Brightcove, Comscore, Chartbeat, Double-click. This improvement in performance of content from these providers can probably be regarded as the single most important achievement of the AMP project to date, as it addresses the major area that is beyond the control of the development teams producing news sites.

As one of the AMP team members, Malte Ubl, expressed it:

For AMP I was like: “What if we instrument pages just once and allow configuring the collected data to be sent to N analytics providers?”

So, we went and talked to many of them. And every single one was like: “That sounds like a great idea”.

With this launching really soon in AMP, if you have 15 analytics providers your page will be exactly as heavy as if you only had one.

What AMP is not

Not a solution for every site

AMP is not a universal panacea: it's only really applicable to templated content-based sites, and not really suitable for hand-crafted sites, which could be actually faster than AMP if done correctly.

Interestingly, the AMP team found that, of the major news organisations they partnered with to launch AMP, all but one reported that the AMP version of their content loaded in the browser significantly faster than the non-AMP version, with load times often improved by 50%-100% or more.

The one news organisaton whose AMP site actually performed 15% slower than their normal site was The Guardian, who everyone I think agrees were already doing a pretty good job of optimising their site before AMP appeared.

Not a great mechanism for custom content

AMP's focus is on producing a visual mobile experience that's leaner in some respects than it could be otherwise, and this means that it's not well suited to producing graphic one-off content, such as snow-falls, interactives and infographics.

As Thomas Wilburn from the Seattle Times mentioned in the Source article:

“The interactives team at the Seattle Times probably won’t use AMP directly at all. Our whole mission is to take advantage of everything a browser can do to tell stories–we’re already using best practices for fast pages, and almost everything we do requires custom JavaScript. But our stuff can’t go in our existing CMS either: we’ve had to find workarounds like responsive iframes or just hosting our own pages wholesale.

AMP isn’t really aimed at content like ours, which is a splashy but tiny percentage of everything the news industry puts out. It’s aimed at the article pages that IT departments write, where all our standard text content goes. Because generally, those pages suck.”

That said, there is at least one example from Google where an interactive treatment was achieved within the AMP restrictions, making heavy use of iframes to present the interactive elements.

AMP is geared towards content generators

Given their function in being a large producer of the sort of templated content that the AMP team are targetting, it should be no surprise that there is already support for AMP on Wordpress.com, as well as a plugin allowing those self-hosting their Wordpress sites to easily produce AMP-powered pages.

Medium have also announced that they will be supporting AMP, and we can probably expect other content publishing platforms to adopt AMP over the next few months.

AMP can also be seen as a good fit for those building progressive web apps, another recent technology paradigm that is also being heavily promoted by Google.

Progressive web apps offer some of the advantages enjoyed up to now by mobile apps, including fast load times, offline caching of content, and easy addition to the devices home screen, and allow web developers to better compete with mobile apps.

And if you think that mobile web apps are gaining advantages to the detriment of their app-based cousins, it should be noted that the convergence of mobile and web apps is happening from both directions, with deep-linking of app content offering mobile developers access to one of the web's characteristic advantages.

What's good for Google is good for the web

We shouldn't consider that Google are being solely altruistic with AMP — Google's business model is largely predicated on a healthy web economy, and although they control a number of aspects of the mobile app economy, they are in an on-going battle for advertising revenue with the likes of Facebook, who are successfully building up their share of the mobile app advertising market.

So, ensuring that the mobile web works fast and as seamlessly as possible with mobile apps can only be regarded as good business sense on Google's part.

AMP restrictions

In order to produce an AMP-powered site, you'll have to limit the way in which you create your pages, and major AMP restrictions include the following:

  • CSS must be inlined in the head, and must be no larger than 50K (i.e. uncompressed)
  • The only JavaScript directly allowed on the page (i.e. not in iframes) is the AMP JavaScript library
  • Certain performance-expensive CSS selectors and HTML tags are not allowed, with AMP providing custom HTML tags in place of some, for example the <amp-img> tag instead of the normal <img> tag
  • Third-party content is typically iframed in AMP-conformant components
  • As a consequence, third-party code is much more restricted in what it can do; for example interstitals or take-over ads are not easily acheiveable on AMP-powered pages.

The good news

It's not all bad news though, and a number of the features that we consider essential on the modern web have good support under AMP:

  • Web fonts are privileged, in that they are treated as the first HTTP request to be actioned on the page
  • Most CSS selectors are allowed, and of those not allowed, the important (!) qualifier is probably going to be the one that developers miss the most
  • AMP provides plenty of AMP-specific components for media including video, slideshows, audo and images
  • Third-party JavaScript is allowed within the confines of iframes

AMP performance objectives

AMP considers performance not only in terms of speed, but also in terms of a better user experience when presenting content to the user as the page is loading.

This includes allowing the browser to determine the layout geometry of page components without having to fetch the external assets, such that the content doesn't jump around as the page is loading, and recommending the use of a CSS animation that fades in the page content only when it's ready for viewing.

“Predictable performance is a key design goal for AMP HTML. Primarily we are aiming at reducing the time until the content of a page can be consumed / used by the user. In concrete terms this means that:
HTTP requests necessary to render and fully layout the document should be minimized.
Resources such as images or ads should only be downloaded if they are likely to be seen by the user.

Browsers should be able to calculate the space needed by every resource on the page without fetching that resource.”

Learning from AMP

A number of the techniques that AMP employs can be thought of as simply good practice, and can be used without necessarily having to adopt AMP itself.

The easy stuff

  • Ensure that there are zero HTTP requests until fonts start downloading
  • Inline critical CSS, and keep overall size small
  • Use resource hints: preload / preconnect / prefetch
  • Allow browsers to calculate size of all components before fetching
  • Lazy-loading of images and ads, such that only those that are in the viewport, or shortly to be in the viewport, are loaded
  • Restrict CSS animations to GPU-friendly opacity and transform
  • Make use of service workers to control caching

The harder stuff

There's a number of other techniques we can cherry-pick from AMP, though these may be harder to achieve than they would if we were directly using AMP:

  • Keep third-party JS out of the critical path: async / defer loading of scripts
  • Iframe expensive third-party JS, so that document.write doesn’t block overall page rendering
  • Minimise style / layout calculations, using fastdom

Happily, implementing HTTP2 will go some way to promoting faster loading of pages, expecially if you use server-push and take advantage of pipelining assets through a single TCP connection.

Specific techniques

Looking through the AMP code, there's a few techniques that stand out as being particularly useful:

Preconnect polyfill

AMP implements a simple preconnect polyfill in the form of an intentional 404:

const url = origin + '/amp_preconnect_polyfill?' + Math.random();
const xhr = new XMLHttpRequest();
xhr.open('HEAD', url, true);
xhr.send();

“Preconnecting executes DNS lookup, TCP and SSL handshake. This saves 100+ms even on WIFI and can be seconds faster on a crappy mobile connection.”

Prefetch Polyfill

const prefetch = document.createElement('link');
prefetch.setAttribute('rel', 'prefetch');
prefetch.setAttribute('href', url);
document.head.appendChild(prefetch);

The above doesn’t work on Safari iOS; so alternatively (but wastefully):

new Image().src = urlToPrefetch

This will prefetch the URL and when it is actually fetched, it is served from cache. However, next time, when the resource is cached, but it wasn’t an image, it will fetch the resource again which wastes bandwidth.

Reduce Use of ES6 Polyfills

This may give developers piling into ES6 some pause for thought:

“We love ES6 and we love Babel, but unfortunately it turns out that some of its polyfills are heavy with respect to JavaScript size. Quite reluctantly we forked the core-js-shim (just one file) and only kept Array.from, Promise and Math.sign out of all the ES6 goodness.

Additionally we limited the syntactical ES6 features we use in the project to those that can be transpiled efficiently by Babel and created a custom Babel helpers file for that purpose”

The (practically) impossible

There are some techniques that AMP use which are probably very difficult to implement in large scale content publishing sites, including the coordiantion between iframes:

“AMP sandboxes all third party JS in cross-origin iframes.

Whichever is the first third party sandbox iframe on a page declare themselves as “master iframe” and then the second and further frames try to find that master in the parent.

This way we always have one special iframe that is the “master iframe”. This allows easy sharing of resources across iframes. Work can be done only once and reused by all the iframes that need it.”

AMP: the (possible) future

The AMP project is ongoing, and recent commentary from the AMP has been interesting in sketching out future developments.

JavaScript gets more privileges

Currently, AMP restricts custom and third-party JavaScript to second-class citizen status, only being able to operate within iframes.

In a piece about improving concurrency, Matli Ubl described his vision for AMP adopting a coordination role for controlling the execution and scheduling of other JavaScript, such that smooth page performance can be maintained at all times.

This would then allow custom and third-party JavaScript to be libterated from their iframe ghettos, and operate once more in an environment where they have access to the full page model.

Content Performance Policy

In a recent article, Tim Kadlec was critical of AMP's role, and posited the use of browser directives indicating what performance boundaries are not negotiable, using a mechanism similar to Content Security Policy.

As a result of this article, the AMP team got together with Tim Kadlec and Yoav Weiss, and drafted a proposal for something they're calling Sandbox Policy.

The Sandbox Policy is inspired by AMP and shares certain concepts and goals. By having a browser-enforced mechanism of “self-control”, i.e. the ability to modify or disable certain web platform capabilities, it enables the following two scenarios:

  • Developers can lock down their application against regressions caused by own and third party resources; it enables violation auditing and reporting against specified standards.
  • Third parties can validate enforced policies and use them as signals about runtime/UX/performance characteristics of the content.

This isn't envisaged as being a replacement for AMP, but rather a mechanism that could be used with or without AMP to enforce performance guidelines in the browser.

It'll be interesting to see what adoption this proposal gets, and it'd be great if we see a mechanism like this adopted across the board by the browser manufacturers.

Fast is important

Although those of us living in well-connected cities in the developed world take (reasonably) fast internet access for granted, we'd still find ourselves benefiting from the use of AMP as a mechanism to combat the year-on-year page bloat that we've been seeing for a while now, and which serves to obviate any advantage that we get from having faster devices and better network speeds.

And for those of us living in not-so-well-connected areas of the world, or still stuck on 3G connections, AMP provides something that approaches a seamless browsing experience.

Further reading

Reactions from News Media Organisations

More about AMP