There are many factors that can contribute to poor web performance. AMP is able to solve performance issues and deliver pages instantly because it follows web performance best practices. But AMP is not magic: anyone can build fast pages without AMP if they follow web development best practices. This is a point that the AMP team has made on several occasions: an AMP page won't be faster than a hand-tooled page, if you know what you're doing. It will be faster than the average mobile webpage, however: AMP is about bringing best practices to the masses.
In addition to the best practices that it implements, AMP imposes restrictions that developers must follow to guarantee a certain baseline performance.
- JavaScript: All JavaScript is loaded asynchronously and is non-blocking. No user JavaScript is allowed in the main page (although you can include JavaScript in iframes that can't block the main page render).
- Static resource sizing: External resources such as images, videos, and ads must specify their sizes statically. This means that AMP can calculate the position of all elements and page layout before anything is downloaded.
- CSS inlining and limitations: CSS must be inlined in the head of the AMP page and is limited to 50 KB per page. Some CSS is restricted, including the
* selector
, thenot selector
, thefilter
property, and the!important
declaration. Only GPU-accelerated CSS animations and transitions are permitted. If the GPU can't handle an effect, then the browser must perform the required computation instead, slowing down the page render. Specifically, onlytransform
andopacity
properties can be animated. - Web fonts: Web fonts can only be loaded from white-listed providers.
- Optimized resource loading: AMP takes control of resource downloading from the browser. Only items that are above-the-fold, or that are likely to be seen by the user, are fetched.
- Efficient pre-rendering: When possible, AMP pages are pre-rendered in the background. This is where things get really interesting!
AMP pre-rendering deserves a special mention here. It's used to boost the loading time of pages in the AMP cache. With AMP-HTML and AMP-JS, you get fast web pages. But with pre-rendering, you get instant pages.
Pre-rendering works by using a hidden iframe to download and render AMP pages in the background, even before the user has decided to visit them. The embedding page loads a hidden iframe with the AMP page content. The browser then loads the AMP runtime and starts to render the page. Since the AMP runtime manages resource loading, nothing else is loaded by the browser at this point (although the AMP runtime might decide to download necessary above-the-fold resources).
If the user clicks a pre-rendered AMP link, all the work to render the page has already been completed, so it can be displayed instantly simply by making the iframe visible. The JavaScript component that manages the pre-rendering iframe is called the AMP Viewer.