AMP

Cumulative Layout Shift (CLS) in AMP

Websites

Content jumps in web pages can be very detrimental for the user experience. As a result of them users might end up clicking the wrong elements or losing their reading position – thereby causing lower engagement rates, higher bounce rates and ultimately lost business.

In this post we’ll analyze how AMP mitigates these content shifts, allowing us to create user-friendly experiences on the web with little effort, thanks to its internal layout system.

We’ll also review different ways you can measure shifts in AMP and non-AMP pages, by using different tools.

Overview

Many times when visiting web pages, users notice that the page content jumps.

News sites, for example, tend to suffer from layout shifts: it’s not uncommon to be reading an article and noticing that the text moves down to make space for some resource like a video, an image or an ad.

AMP however was designed to be different, and AMP components and design principles make it near impossible to trigger layout shifts. This happens thanks to the AMPHTML Layout System, which lets AMP size the page elements before any remote resources, like images, are completed. As a result, rendering and scrolling jank is reduced, which contributes to a much better user experience.

Up until recently, it was hard to measure the exact impact of layout shifts in sites. Now thanks to a new metric: Cumulative Layout Shift (CLS), we can have a more exact idea of how meaningful this is.

The Analysis

The CLS score is based on the layout instability API, which detects when an element that is visible in the viewport changes its start position between two frames. A single shift is bound between 0-1, where 1 means that all of the visible content has shifted. The overall CLS score is the cumulated value of all layout shifts happening on page load.

To see how AMP performs with respect to CLS in the wild, we used a puppeteer based script to analyze a random set of 560 URLs from 450 different domains. The pages selected are largely from different domains, spanning different categories and have a paired AMP version, which we checked for validity first. As AMP is historically mostly implemented for mobile, we restricted the analysis to mobile viewports and connections, but be aware that CLS as a metric is obviously also very important for desktop, and should be measured and tracked there as well. Within our test set we found that CLS in AMP frequently outperformed the non-AMP version.

In 71% of cases the AMP version has a smaller CLS score than the canonical, and in fact in 86% of cases CLS for AMP is zero, as expected due to its design paradigms of keeping layout stable. 

There are use cases where layout-shifts are impossible to avoid, for instance when user-consent is needed and AMP team is currently investigating to minimize the effect on CLS even more. 

In the following section, we’ll analyze different ways to calculate CLS in AMP, including the method we used to arrive at the previous conclusions.

Calculating Layout Shifts in AMP Pages

In HTML pages you can measure CLS by executing a snippet of JS code. In AMP you can’t run custom JS code outside AMP components, or <amp-script>, but here are some easy ways of obtaining this score through different tools:

1. CLS Calculator tool:

The CLS Calculator tool lets you input a URL and easily obtain its CLS score. 

Here are some steps of how to run this, by using a site completely built on AMP: amp.dev:

1. Go to https://layoutstability.rocks/

2. Enter a URL. In this case, amp.dev.

3. Run “Get CLS”.

The test returns the CLS value associated with the page:

In this case, the value of CLS is zero, which means that elements in the page haven’t shifted. As said before, this is one of the benefits of AMP, which leads to a better user experience.

The tool has another great feature: if you have a site that uses AMP in “Paired Mode”, meaning that you are publishing AMP and non-AMP versions of your pages, you can enter the canonical URL and will return a comparison between AMP and non-AMP pages.

Feel free to use this tool on your own site.

2. Lighthouse:

Lighthouse, another popular web performance tool, has recently incorporated CLS as a metric (currently in beta).

Here are the steps to obtain a report for an AMP-First site: amp.dev:

1. Open the command line tool.

2. Run: npm install -g lighthouse@next to install the cli tool.

3. Run: lighthouse https://amp.dev to generate a report.

This will generate an HTML file in the current directory. 

Opening the file in the browser shows the CLS value of the site (in the case of amp.dev, zero):

3. Webpagetest:

Webpagetest is one of the most popular web performance tools. It lets you obtain the main performance metrics for a website, simulating different devices and locations.

The tool currently provides CLS as a metric, inside one of the internal options. This could change in the future, making the metric available in the main results page.

To obtain the CLS for amp.dev:

1. Go to https://www.webpagetest.org/

2. Enter https://amp.dev as URL.

3. Click “Start Test”.

4. Once the results are received, click on “View JSON result” in the top left corner:

This will return a JSON file with the results of the test.

Searching for the first occurrence of “CumulativeLayoutShift”, will show the value of this metric, which is zero as in the previous tests.

4. Puppeteer:

Puppeteer can also be a great option for automatic retrieval of CLS for a given website, or to even batch process many websites. Integration through puppeteer makes also sense for testing and QA purposes. 

A (truncated) example snippet on how to get CLS with Puppeteer can look like this (full code here):

const page = await browser.newPage();
const client = await page.target().createCDPSession();

// throttle network and CPU as needed, see e.g. here:
// https://michaljanaszek.com/blog/test-website-performance-with-puppeteer
await client.send('Network.enable');
await client.send('ServiceWorker.enable');
await client.send('Network.emulateNetworkConditions', Good3G);
await client.send('Emulation.setCPUThrottlingRate', { rate: 4 });
await page.emulate(phone);

// inject a function with the cls measurement code code from :
// https://web.dev/cls/#measure-cls-in-javascript
await page.evaluateOnNewDocument(calcJank);
await page.goto(url, { waitUntil: 'load', timeout: 60000});
await page.evaluate(calcJank);
let cls = await page.evaluate(
  () => window.cumulativeLayoutShiftScore 
);Code language: JavaScript (javascript)

Conclusion

Visual stability is a very important aspect of the user experience. AMP’s architecture is intentionally designed to avoid layout shifts and make it easier to create user-friendly experiences on the web.

In this post we have explored different ways of calculating Cumulative Layout Shift for AMP pages. 

  • For sites that use AMP as their primary framework, evaluating this metric can help them understand better the benefits that AMP can bring to users.
  • For those using the “Paired AMP” approach, comparing  the value of CLS on their AMP vs. non-AMP versions of the pages, can help them understand which performs better and guide future technical decisions.
  • For those that are not yet using AMP, running the previous tests in AMP pages from popular sites (for example, news publishers) can give a better understanding of the benefits AMP could potentially bring to their own sites.

Written by Demián Renzulli, Martin Schierle, and Gilberto Cocchi, Web Ecosystem Consultants, Google