Refresh to see this hosted in an app shell!

A new approach to web performance

Web performance is not unexplored territory for the tech community: books have been written about it, many talks have been given – there is even an entire conference series dedicated to the topic. However, users still frequently see poor web performance in the wild, particularly on mobile devices. Consumption of news articles, and similar relatively static content, is often painfully slow, with pages taking a long time to load. Even after text becomes visible, pages continue to build up over many seconds, as ads and images come into display. The result is an often jarring experience of janky scrolling and users needlessly losing their reading position.

Over the last several months, discussions between publishers and technology companies began in earnest about the need to improve the entire mobile content ecosystem for everyone – publishers, consumer platforms, creators, and users. We asked ourselves, how can we improve this problem? In some ways, the trend nowadays is to switch to native apps on mobile, but we have read those books, and seen those presentations, and we know that the web can be fast if best practices are followed. To make the web fast at scale, we want to make it easier to create documents that are fast-by-default.

This is a really hard problem to solve, so we decided to reduce scope. The web today is many things: an application platform, an e-commerce platform, a content platform, a gaming platform, and so much more. We decided to focus entirely on static content as it lends itself to more radical optimization approaches that are easier to apply across the board.

We began to experiment with an idea: could we develop a restricted subset of the things we’d use from HTML, that's both fast and expressive, so that documents would always load and render with reliable performance? That experiment has culminated in a promising proof of concept we call Accelerated Mobile Pages (AMP). AMP HTML is built on existing web technologies, and the documents written in it render in all modern web browsers and web views. In fact, this page is, itself, an AMP HTML document.

The page you are currently reading is an AMP HTML document.

We think AMP HTML is promising, but we know it's not complete. We are sharing our proof-of-concept on GitHub to start a conversation about how to make static content on the web fast. We want to collaborate with the entire web community to develop this promising idea into something more real, sharing our techniques, ideas, and code.

One thing we realized early on is that many performance issues are caused by the integration of multiple JavaScript libraries, tools, embeds, etc. into a page. This isn’t saying that JavaScript immediately leads to bad performance, but once arbitrary JavaScript is in play, most bets are off because anything could happen at any time and it is hard to make any type of performance guarantee. With this in mind we made the tough decision that AMP HTML documents would not include any author-written JavaScript, nor any third-party scripts.

JavaScript is the core building block for advanced web apps, but for static content it may not always be required: for a headline, some text and an image you do not need JS. Looking further into the content being created on the web nowadays, there are, however, things like lightboxes, various embeds, polls, quizzes and other interactive features that cannot easily be implemented without JavaScript. But the web platform has a great solution: custom elements and web components. AMP components may have JavaScript under the hood, but it is coordinated with other AMP components, so its composition into the page doesn’t cause performance degradation. If AMP HTML provided the right custom elements, we might be able to get rid of arbitrary JavaScript for these documents altogether.

AMP HTML loves CSS!

So, AMP HTML comes with strong limitations on JS. What about CSS? AMP HTML loves CSS! We do add some best practice enforcement, but we do want AMP HTML documents to look like their authors intended them to, and so allowing extensive styling is core to the platform.

Ads and analytics – while critical for publishers – are a big part of the performance problem and so they must be a big part of the solution. Sites often deploy many analytics providers. Ad serving is also a complicated ecosystem. Embedding an ad or analytics often implies giving up control of what eventually happens to a site because they can typically inject any JavaScript they want into pages. AMP HTML does not allow this. We realize that both ads and analytics are an important element of monetization on the web, and so we need to support them: our goal is to realign monetization with great user experience.

AMP HTML is taking the following approach to analytics: so-called “tracking pixels” can be embedded into AMP documents as long as they don’t use JavaScript. They typically come with a noscript version that makes this easy. More advanced analytics are currently not supported. Our vision is to deploy a single, unified, auditable, high performance, open source analytics library with AMP HTML that can report to various existing analytics provider backends, so it is possible to use the existing ecosystem without overloading a page with analytics software.

We’ve taken first steps to make ads in AMP HTML better, but we aren’t done yet. AMP HTML doesn’t allow JavaScript so ads cannot be directly embedded – instead they live in sandboxed iframes with no access to the primary document. Relying on iframes solves some of the worst performance pitfalls with ads, in particular with respect to document.write. We also prioritize ads lower during loading than other content and optimize load timing to avoid jank. Ads in AMP files can still be heavyweight, so there is still a lot of work to do for us.

AMP HTML is pretty fast.

So, how fast is AMP HTML? Pretty fast. In a sample of pages our early partners created we are seeing performance improvements measured through Speed Index between 15% and 85%. This was measured with a simulated 3G connection and a simulated Nexus 5 device. The best part is you don't need to be a performance expert to get this; best practices are baked right in. And as we optimize AMP HTML in the future, all pages benefit.

But how do we get from good to, let’s say, instant? We’ll cheat :) AMP documents are from the ground up designed to be efficiently pre-renderable. Browsers have long supported pre-rendering through the <link rel=prerender> tag, but they need to be conservative about this mechanism because prerendering can be expensive. With AMP HTML we added the ability to tell a document: render yourself, but only as far as what is visible above the fold and only elements which are not CPU intensive to minimize the cost of pre-rendering. With this mechanism in place, referrers of AMP document can initiate rendering of docs before the user acts much more aggressively, so that in many cases the document will be done rendering by the time the user clicks.

With all of these techniques in place, AMP HTML documents can be loaded with a small set of HTTP requests: the document itself, custom fonts (if used) and what we call the AMP JavaScript library that implements the AMP custom elements and resource loading.

Our goal with AMP HTML is reliable performance, so we designed it to be easily cacheable by content delivery networks (CDNs). Google is offering a service that delivers AMP HTML documents given their URL through its CDN. Others can use this service or make their own or serve AMP HTML pages from a plain-old-web-server.

Resources must declare their sizing up-front

This brings us to the final topic that makes AMP HTML unique: all resource loading is controlled by the AMP library and, more importantly, resources must declare their sizing up-front. Document authors have to state resource sizes explicitly. This doesn’t mean that resources can’t be responsive – they can be, but their aspect ratio or dimensions needs to be inferable from the HTML alone. This means that after initial layout, an AMP document does not change until user action. An ad at the top of the page can’t suddenly say: “I want to be 200 pixels high instead of 50.” This dramatically reduces jank and prevents users from losing their place in the document. All custom elements are subject to this restriction. Placement on the screen can be reserved while their implementations download asynchronously. This gets us lazy loading with zero visual jank.

To summarize: AMP HTML is a specialized subset of HTML with custom elements that provides reliable performance and instant loading of static content. Nothing about the project is set in stone. We are sharing an early version of the AMP HTML spec as well as a prototype implementation on GitHub and we are looking forward to collaborating with the community on all aspects of the project. We expect there are still low (or not so low) hanging fruit for performance optimization that we missed, so if you are an expert in web performance or just want to dig in we’d love your help. Also, if you happen to know a lot about publishing documents on the internet we’d love your input: Maybe some of our restrictions are a bit too drastic for the things you work on. We’d love to hear about those cases, so we can thoughtfully extend the capabilities of AMP HTML while keeping pages lean and fast.
See you over on GitHub!