<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>https://web.dev/</id>
  <title>Michal Mocny on web.dev</title>
  <updated>2026-04-15T23:21:06Z</updated>
  <author>
    <name>Michal Mocny</name>
  </author>
  <link href="https://web.dev/authors/mmocny/feed.xml" rel="self"/>
  <link href="https://web.dev/"/>
  <icon>https://web-dev.imgix.net/image/admin/urYfROhm806fvOPRMsRg.jpg?auto=format</icon>
  <logo>https://web.dev/images/shared/rss-banner.png</logo>
  <subtitle>Our latest news, updates, and stories by Michal Mocny.</subtitle>
  
  
  <entry>
    <title>Using the Web Vitals extension to debug Core Web Vitals issues</title>
    <link href="https://web.dev/debug-cwvs-with-web-vitals-extension/"/>
    <updated>2023-05-04T00:00:00Z</updated>
    <id>https://web.dev/debug-cwvs-with-web-vitals-extension/</id>
    <content type="html" mode="escaped">&lt;p&gt;The &lt;a href=&quot;https://chrome.google.com/webstore/detail/web-vitals/ahfhijdlegdabablpippeagghigmibma&quot; rel=&quot;noopener&quot;&gt;Web Vitals extension&lt;/a&gt; provides easy access to Core Web Vitals diagnostic information to help developers measure, and address Core Web Vitals issues. It supplements the other tools provided by the Chrome team to aid developers in improving the experiences on their websites.&lt;/p&gt;
&lt;p&gt;We have updated the extension to provide additional debug information to developers to make it easier to understand and address their performance problems.&lt;/p&gt;
&lt;h2 id=&quot;showing-debug-information-in-the-console&quot;&gt;Showing debug information in the console &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/debug-cwvs-with-web-vitals-extension/#showing-debug-information-in-the-console&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The Web Vitals extension has had a &amp;quot;Console Logging&amp;quot; debug option for some time now. It can be enabled in the Options screen:&lt;/p&gt;
&lt;img alt=&quot;Web Vitals Extension Options screen&quot; decoding=&quot;async&quot; height=&quot;434&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/SjuszdY0PADWgETicJNl.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/SjuszdY0PADWgETicJNl.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/SjuszdY0PADWgETicJNl.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/SjuszdY0PADWgETicJNl.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/SjuszdY0PADWgETicJNl.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/SjuszdY0PADWgETicJNl.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/SjuszdY0PADWgETicJNl.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/SjuszdY0PADWgETicJNl.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/SjuszdY0PADWgETicJNl.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/SjuszdY0PADWgETicJNl.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/SjuszdY0PADWgETicJNl.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/SjuszdY0PADWgETicJNl.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/SjuszdY0PADWgETicJNl.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/SjuszdY0PADWgETicJNl.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/SjuszdY0PADWgETicJNl.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/SjuszdY0PADWgETicJNl.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/SjuszdY0PADWgETicJNl.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/SjuszdY0PADWgETicJNl.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;p&gt;Prior to the this last upgrade, this logged the outputs from the &lt;a href=&quot;https://github.com/GoogleChrome/web-vitals&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;web-vitals library&lt;/code&gt;&lt;/a&gt; (that underpins the extension) in a JSON object:&lt;/p&gt;
&lt;img alt=&quot;Web Vitals Extension old console logging&quot; decoding=&quot;async&quot; height=&quot;458&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/iUoyoe41Ik4zNDNRPHKo.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/iUoyoe41Ik4zNDNRPHKo.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/iUoyoe41Ik4zNDNRPHKo.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/iUoyoe41Ik4zNDNRPHKo.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/iUoyoe41Ik4zNDNRPHKo.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/iUoyoe41Ik4zNDNRPHKo.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/iUoyoe41Ik4zNDNRPHKo.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/iUoyoe41Ik4zNDNRPHKo.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/iUoyoe41Ik4zNDNRPHKo.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/iUoyoe41Ik4zNDNRPHKo.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/iUoyoe41Ik4zNDNRPHKo.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/iUoyoe41Ik4zNDNRPHKo.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/iUoyoe41Ik4zNDNRPHKo.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/iUoyoe41Ik4zNDNRPHKo.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/iUoyoe41Ik4zNDNRPHKo.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/iUoyoe41Ik4zNDNRPHKo.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/iUoyoe41Ik4zNDNRPHKo.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/iUoyoe41Ik4zNDNRPHKo.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;p&gt;This object could then be expanded to get the full details, and elements such as the LCP image, could be hovered over to highlight them in the main panel:&lt;/p&gt;
&lt;img alt=&quot;Web Vitals Extension old console logging with element highlighting&quot; decoding=&quot;async&quot; height=&quot;514&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/oNVOo321R5U3Lqg1xrH6.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/oNVOo321R5U3Lqg1xrH6.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/oNVOo321R5U3Lqg1xrH6.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/oNVOo321R5U3Lqg1xrH6.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/oNVOo321R5U3Lqg1xrH6.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/oNVOo321R5U3Lqg1xrH6.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/oNVOo321R5U3Lqg1xrH6.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/oNVOo321R5U3Lqg1xrH6.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/oNVOo321R5U3Lqg1xrH6.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/oNVOo321R5U3Lqg1xrH6.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/oNVOo321R5U3Lqg1xrH6.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/oNVOo321R5U3Lqg1xrH6.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/oNVOo321R5U3Lqg1xrH6.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/oNVOo321R5U3Lqg1xrH6.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/oNVOo321R5U3Lqg1xrH6.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/oNVOo321R5U3Lqg1xrH6.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/oNVOo321R5U3Lqg1xrH6.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/oNVOo321R5U3Lqg1xrH6.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;p&gt;This was helpful, but the output format was not particularly user friendly, and we thought we could provide a better developer experience. So we have improved the extension to make the most important information more visible—while still including the full object for those wanting more details.&lt;/p&gt;
&lt;h2 id=&quot;new-debug-information-for-each-metric&quot;&gt;New debug information for each metric &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/debug-cwvs-with-web-vitals-extension/#new-debug-information-for-each-metric&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;With the new release, we have added new debug information in a more readable format to help you find and address issues. Different information is provided for each of the metrics, as each one is different.&lt;/p&gt;
&lt;h3 id=&quot;lcp-debug-information&quot;&gt;LCP debug information &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/debug-cwvs-with-web-vitals-extension/#lcp-debug-information&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;For &lt;a href=&quot;https://web.dev/lcp/&quot;&gt;Largest Contentful Paint (LCP)&lt;/a&gt;, we show both the element, and the breakdown of the 4 phases detailed in our &lt;a href=&quot;https://web.dev/optimize-lcp/#lcp-breakdown&quot;&gt;Optimize LCP&lt;/a&gt; guide:&lt;/p&gt;
&lt;img alt=&quot;Web Vitals Extension new console logging showing LCP elements and sub-parts&quot; decoding=&quot;async&quot; height=&quot;535&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/HXzKcJORE2nRUI9Pl8Mw.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/HXzKcJORE2nRUI9Pl8Mw.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/HXzKcJORE2nRUI9Pl8Mw.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/HXzKcJORE2nRUI9Pl8Mw.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/HXzKcJORE2nRUI9Pl8Mw.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/HXzKcJORE2nRUI9Pl8Mw.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/HXzKcJORE2nRUI9Pl8Mw.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/HXzKcJORE2nRUI9Pl8Mw.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/HXzKcJORE2nRUI9Pl8Mw.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/HXzKcJORE2nRUI9Pl8Mw.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/HXzKcJORE2nRUI9Pl8Mw.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/HXzKcJORE2nRUI9Pl8Mw.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/HXzKcJORE2nRUI9Pl8Mw.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/HXzKcJORE2nRUI9Pl8Mw.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/HXzKcJORE2nRUI9Pl8Mw.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/HXzKcJORE2nRUI9Pl8Mw.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/HXzKcJORE2nRUI9Pl8Mw.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/HXzKcJORE2nRUI9Pl8Mw.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;p&gt;The LCP time (2,876 milliseconds—or about 2.9 seconds) is highlighted in amber as it is in the &amp;quot;Needs Improvement&amp;quot; category.&lt;/p&gt;
&lt;p&gt;In this example, we see the &lt;code&gt;Resource load time&lt;/code&gt; is the longest time, so to improve your LCP time you would look to optimize that - perhaps by avoiding hosting them on a separate domain, or by using smaller images or more efficient formats. In this case it&#39;s due to being artificially slowed down to demonstrate the output—web.dev is a fast site 😀&lt;/p&gt;
&lt;p&gt;The element can also be hovered over to highlight the image:&lt;/p&gt;
&lt;img alt=&quot;Web Vitals Extension new console logging retains element highlighting on hover&quot; decoding=&quot;async&quot; height=&quot;535&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/8H8ZldOw8y953w7vTpuA.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/8H8ZldOw8y953w7vTpuA.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/8H8ZldOw8y953w7vTpuA.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/8H8ZldOw8y953w7vTpuA.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/8H8ZldOw8y953w7vTpuA.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/8H8ZldOw8y953w7vTpuA.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/8H8ZldOw8y953w7vTpuA.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/8H8ZldOw8y953w7vTpuA.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/8H8ZldOw8y953w7vTpuA.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/8H8ZldOw8y953w7vTpuA.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/8H8ZldOw8y953w7vTpuA.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/8H8ZldOw8y953w7vTpuA.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/8H8ZldOw8y953w7vTpuA.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/8H8ZldOw8y953w7vTpuA.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/8H8ZldOw8y953w7vTpuA.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/8H8ZldOw8y953w7vTpuA.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/8H8ZldOw8y953w7vTpuA.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/8H8ZldOw8y953w7vTpuA.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;p&gt;Right clicking on the element also allows you to reveal it in the elements panel.&lt;/p&gt;
&lt;p&gt;Here the LCP element is an image, and hovering over that in the console on the right, also highlights that element on the site on the left.&lt;/p&gt;
&lt;h3 id=&quot;cls-debug-information&quot;&gt;CLS debug information &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/debug-cwvs-with-web-vitals-extension/#cls-debug-information&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Shifts contributing to &lt;a href=&quot;https://web.dev/cls/&quot;&gt;Cumulative Layout Shift (CLS)&lt;/a&gt; are now also listed, and can be hovered over to highlight the relevant element:&lt;/p&gt;
&lt;img alt=&quot;Web Vitals Extension new console logging showing each CLS element shift&quot; decoding=&quot;async&quot; height=&quot;448&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/v1kaVvcekk5oLWuGHAkd.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/v1kaVvcekk5oLWuGHAkd.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/v1kaVvcekk5oLWuGHAkd.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/v1kaVvcekk5oLWuGHAkd.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/v1kaVvcekk5oLWuGHAkd.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/v1kaVvcekk5oLWuGHAkd.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/v1kaVvcekk5oLWuGHAkd.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/v1kaVvcekk5oLWuGHAkd.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/v1kaVvcekk5oLWuGHAkd.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/v1kaVvcekk5oLWuGHAkd.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/v1kaVvcekk5oLWuGHAkd.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/v1kaVvcekk5oLWuGHAkd.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/v1kaVvcekk5oLWuGHAkd.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/v1kaVvcekk5oLWuGHAkd.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/v1kaVvcekk5oLWuGHAkd.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/v1kaVvcekk5oLWuGHAkd.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/v1kaVvcekk5oLWuGHAkd.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/v1kaVvcekk5oLWuGHAkd.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;p&gt;The above screenshot shows 2 shifts, the first made up of two elements (when the banner image is loaded and the content beneath it is shifted downloaded), and the second of 4 elements (when the dynamic ad is loaded and most of the page is shifted downwards).&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;h2&lt;/code&gt; element is being hovered over in this screenshot in the console on the right, and you can see this highlights the element on the site on the left.&lt;/p&gt;
&lt;aside class=&quot;aside flow bg-tertiary-box-bg color-tertiary-box-text&quot;&gt;&lt;p class=&quot;cluster &quot;&gt;&lt;span class=&quot;aside__icon box-block &quot;&gt;&lt;svg width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; role=&quot;img&quot; aria-label=&quot;Lightbulb&quot; fill=&quot;currentColor&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;   &lt;path d=&quot;M9 21c0 .55.45 1 1 1h4c.55 0 1-.45 1-1v-1H9v1zm3-19C8.14 2 5 5.14 5 9c0 2.38 1.19 4.47 3 5.74V17c0 .55.45 1 1 1h6c.55 0 1-.45 1-1v-2.26c1.81-1.27 3-3.36 3-5.74 0-3.86-3.14-7-7-7zm2.85 11.1l-.85.6V16h-4v-2.3l-.85-.6A4.997 4.997 0 017 9c0-2.76 2.24-5 5-5s5 2.24 5 5c0 1.63-.8 3.16-2.15 4.1z&quot;&gt;&lt;/path&gt; &lt;/svg&gt;&lt;/span&gt;&lt;strong&gt;Important&lt;/strong&gt;&lt;/p&gt;&lt;div class=&quot; flow&quot;&gt; &lt;p&gt; Note that the shifted elements are not the elements &lt;em&gt;causing&lt;/em&gt; the shift, but the ones that were &lt;em&gt;impacted&lt;/em&gt; by any shifts. &lt;/p&gt; &lt;p&gt; However, as per the above example, this should usually be enough to help you identify the cause of the shift by looking at the element which is either above the first shifted element (for inserted elements) or the first element itself (if this is expanded and so shifts itself). &lt;/p&gt; &lt;/div&gt;&lt;/aside&gt;
&lt;h3 id=&quot;fid-debug-information&quot;&gt;FID debug information &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/debug-cwvs-with-web-vitals-extension/#fid-debug-information&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;For &lt;a href=&quot;https://web.dev/fid/&quot;&gt;First Input Delay (FID)&lt;/a&gt; we show the affected element (which again, can be hovered over to highlight it on the page) and the interaction type, along with the full JSON object as usual:&lt;/p&gt;
&lt;img alt=&quot;Web Vitals Extension new console logging showing FID target and type&quot; decoding=&quot;async&quot; height=&quot;448&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/f8JI8akIhiqfA7WHWfRz.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/f8JI8akIhiqfA7WHWfRz.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/f8JI8akIhiqfA7WHWfRz.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/f8JI8akIhiqfA7WHWfRz.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/f8JI8akIhiqfA7WHWfRz.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/f8JI8akIhiqfA7WHWfRz.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/f8JI8akIhiqfA7WHWfRz.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/f8JI8akIhiqfA7WHWfRz.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/f8JI8akIhiqfA7WHWfRz.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/f8JI8akIhiqfA7WHWfRz.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/f8JI8akIhiqfA7WHWfRz.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/f8JI8akIhiqfA7WHWfRz.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/f8JI8akIhiqfA7WHWfRz.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/f8JI8akIhiqfA7WHWfRz.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/f8JI8akIhiqfA7WHWfRz.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/f8JI8akIhiqfA7WHWfRz.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/f8JI8akIhiqfA7WHWfRz.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/f8JI8akIhiqfA7WHWfRz.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;h3 id=&quot;inp-debug-information&quot;&gt;INP debug information &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/debug-cwvs-with-web-vitals-extension/#inp-debug-information&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;For &lt;a href=&quot;https://web.dev/inp/&quot;&gt;Interaction to Next Paint (INP)&lt;/a&gt;, we have added two new logs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;INP - the longest interaction&lt;/li&gt;
&lt;li&gt;Interactions - all interactions&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;inp-metric&quot;&gt;INP metric &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/debug-cwvs-with-web-vitals-extension/#inp-metric&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;First up, we highlight the INP metric when it changes:&lt;/p&gt;
&lt;img alt=&quot;Web Vitals Extension new console logging showing INP target, event type, and breakdown&quot; decoding=&quot;async&quot; height=&quot;448&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/kxh8TRS2585OJTZJmWmt.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/kxh8TRS2585OJTZJmWmt.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/kxh8TRS2585OJTZJmWmt.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/kxh8TRS2585OJTZJmWmt.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/kxh8TRS2585OJTZJmWmt.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/kxh8TRS2585OJTZJmWmt.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/kxh8TRS2585OJTZJmWmt.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/kxh8TRS2585OJTZJmWmt.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/kxh8TRS2585OJTZJmWmt.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/kxh8TRS2585OJTZJmWmt.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/kxh8TRS2585OJTZJmWmt.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/kxh8TRS2585OJTZJmWmt.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/kxh8TRS2585OJTZJmWmt.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/kxh8TRS2585OJTZJmWmt.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/kxh8TRS2585OJTZJmWmt.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/kxh8TRS2585OJTZJmWmt.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/kxh8TRS2585OJTZJmWmt.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/kxh8TRS2585OJTZJmWmt.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;p&gt;Similar to LCP, the extension breaks down the INP time to show three phases:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Input delay&lt;/li&gt;
&lt;li&gt;Processing time&lt;/li&gt;
&lt;li&gt;Presentation delay&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This helps you identify if the event was slow due to being held up by other events (&lt;strong&gt;input delay&lt;/strong&gt;), as the event handler itself was slow due to your code (&lt;strong&gt;processing time&lt;/strong&gt;), if the post-processing render delay was the reason (&lt;strong&gt;presentation delay&lt;/strong&gt;), or a combination of two or more of these.&lt;/p&gt;
&lt;h4 id=&quot;interactions&quot;&gt;Interactions &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/debug-cwvs-with-web-vitals-extension/#interactions&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;INP can be slow due to previous interactions blocking the main thread, and thus causing a high input delay. For this reason, we list all interactions in a similar format to the INP logging:&lt;/p&gt;
&lt;img alt=&quot;Web Vitals Extension new console logging showing all interactions&quot; decoding=&quot;async&quot; height=&quot;448&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/k2uHWUQXoq5fWGOQ4yyF.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/k2uHWUQXoq5fWGOQ4yyF.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/k2uHWUQXoq5fWGOQ4yyF.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/k2uHWUQXoq5fWGOQ4yyF.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/k2uHWUQXoq5fWGOQ4yyF.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/k2uHWUQXoq5fWGOQ4yyF.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/k2uHWUQXoq5fWGOQ4yyF.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/k2uHWUQXoq5fWGOQ4yyF.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/k2uHWUQXoq5fWGOQ4yyF.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/k2uHWUQXoq5fWGOQ4yyF.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/k2uHWUQXoq5fWGOQ4yyF.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/k2uHWUQXoq5fWGOQ4yyF.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/k2uHWUQXoq5fWGOQ4yyF.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/k2uHWUQXoq5fWGOQ4yyF.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/k2uHWUQXoq5fWGOQ4yyF.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/k2uHWUQXoq5fWGOQ4yyF.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/k2uHWUQXoq5fWGOQ4yyF.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/k2uHWUQXoq5fWGOQ4yyF.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;p&gt;This allows you to &amp;quot;live trace&amp;quot; a website by interacting with it and seeing in the console which interactions, in which combinations, are likely to cause an INP problem.&lt;/p&gt;
&lt;p&gt;This also allows you to identify multiple slow interactions, rather than just the largest INP interaction to help you avoid the feeling of chasing your tail when improving your responsiveness.&lt;/p&gt;
&lt;h2 id=&quot;filtering-the-console-logs&quot;&gt;Filtering the console logs &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/debug-cwvs-with-web-vitals-extension/#filtering-the-console-logs&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;All this extra information, while useful, can be distracting if you are doing other development unrelated to Core Web Vitals, or are only interested in one particular Core Web Vital at that time.&lt;/p&gt;
&lt;p&gt;You can use the &lt;a href=&quot;https://developer.chrome.com/docs/devtools/console/reference/#filter&quot; rel=&quot;noopener&quot;&gt;Console filtering options in DevTools&lt;/a&gt; to filter out some or all of the messages:&lt;/p&gt;
&lt;img alt=&quot;Using console filtering options&quot; decoding=&quot;async&quot; height=&quot;448&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/NOA3kNu5rKMzkw7iAyW7.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/NOA3kNu5rKMzkw7iAyW7.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/NOA3kNu5rKMzkw7iAyW7.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/NOA3kNu5rKMzkw7iAyW7.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/NOA3kNu5rKMzkw7iAyW7.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/NOA3kNu5rKMzkw7iAyW7.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/NOA3kNu5rKMzkw7iAyW7.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/NOA3kNu5rKMzkw7iAyW7.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/NOA3kNu5rKMzkw7iAyW7.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/NOA3kNu5rKMzkw7iAyW7.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/NOA3kNu5rKMzkw7iAyW7.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/NOA3kNu5rKMzkw7iAyW7.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/NOA3kNu5rKMzkw7iAyW7.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/NOA3kNu5rKMzkw7iAyW7.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/NOA3kNu5rKMzkw7iAyW7.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/NOA3kNu5rKMzkw7iAyW7.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/NOA3kNu5rKMzkw7iAyW7.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/W3z1f5ZkBJSgL1V1IfloTIctbIF3/NOA3kNu5rKMzkw7iAyW7.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;ul&gt;
&lt;li&gt;To remove all the extension messages, you can either turn this off in the options or use the &lt;code&gt;-Extension&lt;/code&gt; filter.&lt;/li&gt;
&lt;li&gt;To look at just LCP you can use the &lt;code&gt;Web Vitals Extension LCP&lt;/code&gt; filter.&lt;/li&gt;
&lt;li&gt;To look at just INP and interactions you can use the &lt;code&gt;Web Vitals Extension -LCP -CLS -FID&lt;/code&gt; filter.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We&#39;re trying to keep the number of options for this extension down, but do let us know by raising a &lt;a href=&quot;https://github.com/GoogleChrome/web-vitals-extension/issues&quot; rel=&quot;noopener&quot;&gt;GitHub issue&lt;/a&gt; if DevTools filtering is not sufficient and you would prefer options here.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/debug-cwvs-with-web-vitals-extension/#conclusion&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We hope you find the new debug options in the latest version of the extension useful and that they make it easier to identify and resolve Core Web Vitals issues, improving the  user experiences on your website.&lt;/p&gt;
&lt;p&gt;Do remember that your experiences, on your developer computer, may not be representative of what your real users are experiencing. Check out our &lt;a href=&quot;https://web.dev/field-data-in-the-web-vitals-extension/&quot;&gt;previous blog post on how you can view the CrUX field data for your site in the extension&lt;/a&gt; to get a sense of how aligned your experiences are with your users.&lt;/p&gt;
&lt;p&gt;We would be grateful to hear any feedback on these improvements, or any other suggestions on our &lt;a href=&quot;https://github.com/GoogleChrome/web-vitals-extension/issues&quot; rel=&quot;noopener&quot;&gt;GitHub issues tracker&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;acknowledgements&quot;&gt;Acknowledgements &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/debug-cwvs-with-web-vitals-extension/#acknowledgements&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Hero image by &lt;a href=&quot;https://unsplash.com/@euwars?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText&quot; rel=&quot;noopener&quot;&gt;Farzad&lt;/a&gt; on &lt;a href=&quot;https://unsplash.com/photos/p-xSl33Wxyc?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText&quot; rel=&quot;noopener&quot;&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
</content>
    <author>
      <name>Barry Pollard</name>
    </author><author>
      <name>Michal Mocny</name>
    </author><author>
      <name>Rick Viscomi</name>
    </author><author>
      <name>Brendan Kenny</name>
    </author>
  </entry>
  
  <entry>
    <title>Towards an animation smoothness metric</title>
    <link href="https://web.dev/smoothness/"/>
    <updated>2021-11-03T00:00:00Z</updated>
    <id>https://web.dev/smoothness/</id>
    <content type="html" mode="escaped">&lt;p&gt;You&#39;ve probably experienced pages that &amp;quot;stutter&amp;quot; or &amp;quot;freeze&amp;quot; during scrolling or
animations. We like to say that these experiences are not &lt;em&gt;smooth&lt;/em&gt;. To address
these types of issues, the Chrome team has been working on adding more support
to our lab tooling for animation detection, as well as making steady improvements
to the rendering pipeline diagnostics within Chromium.&lt;/p&gt;
&lt;p&gt;We&#39;d like to share some recent progress, offer concrete tooling guidance, and
discuss ideas for future animation smoothness metrics. As always, we would love
to hear your &lt;a href=&quot;https://web.dev/smoothness/#feedback&quot;&gt;feedback&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This post will cover three main topics:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A quick look at animations and animation frames.&lt;/li&gt;
&lt;li&gt;Our current thoughts on measuring overall animation smoothness.&lt;/li&gt;
&lt;li&gt;A few practical suggestions for you to leverage in lab tooling today.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;what-are-animations&quot;&gt;What are animations? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/smoothness/#what-are-animations&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Animations bring content to life! By making content move, especially in response
to user interactions, animations can make an experience feel more natural,
understandable, and fun.&lt;/p&gt;
&lt;p&gt;But poorly implemented animations, or just adding too many animations, can
degrade the experience and make it decidedly not fun at all. We&#39;ve probably all
interacted with an interface which just added too many &amp;quot;helpful&amp;quot; transition
effects, which actually become hostile to experience when they perform poorly.
Some users therefore actually might
&lt;a href=&quot;https://web.dev/prefers-reduced-motion/&quot;&gt;prefer reduced motion&lt;/a&gt;, a user preference
that you should honor.&lt;/p&gt;
&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt; Learn more about &lt;a href=&quot;https://web.dev/animations/&quot;&gt;animations&lt;/a&gt;, including how to &lt;a href=&quot;https://web.dev/animations-guide/&quot;&gt;create performant animations&lt;/a&gt; and how to &lt;a href=&quot;https://developer.chrome.com/docs/devtools/css/animations/&quot;&gt;inspect animations using developer tooling&lt;/a&gt;. &lt;/div&gt;&lt;/aside&gt;
&lt;h3 id=&quot;how-do-animations-work&quot;&gt;How do animations work? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/smoothness/#how-do-animations-work&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;As a quick recap, the &lt;a href=&quot;https://web.dev/animations-overview/#pipeline&quot;&gt;rendering pipeline&lt;/a&gt;
consists of a few, &lt;strong&gt;sequential&lt;/strong&gt; stages:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong style=&quot;font-weight:700;color:#6251A2&quot;&gt;Style:&lt;/strong&gt; Calculate the
styles that apply to the elements.&lt;/li&gt;
&lt;li&gt;&lt;strong style=&quot;font-weight:700;color:#6251A2&quot;&gt;Layout:&lt;/strong&gt; Generate the
geometry and position for each element.&lt;/li&gt;
&lt;li&gt;&lt;strong style=&quot;font-weight:700;color:#78A55A&quot;&gt;Paint:&lt;/strong&gt; Fill out the
pixels for each element into layers.&lt;/li&gt;
&lt;li&gt;&lt;strong style=&quot;font-weight:700;color:#78A55A&quot;&gt;Composite:&lt;/strong&gt; Draw the
layers to the screen.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;While there are many ways to define animations, they all fundamentally work via
one of the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Adjusting &lt;strong style=&quot;font-weight:700;color:#6251A2&quot;&gt;layout&lt;/strong&gt;
properties.&lt;/li&gt;
&lt;li&gt;Adjusting &lt;strong style=&quot;font-weight:700;color:#78A55A&quot;&gt;paint&lt;/strong&gt;
properties.&lt;/li&gt;
&lt;li&gt;Adjusting &lt;strong style=&quot;font-weight:700;color:#78A55A&quot;&gt;composite&lt;/strong&gt;
properties.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Because these stages are sequential, it is important to define animations in
terms of properties that are further down the pipeline. The earlier the update
happens in the process, the greater are the costs and it&#39;s less likely to be
smooth. (See &lt;a href=&quot;https://web.dev/rendering-performance/&quot;&gt;Rendering
performance&lt;/a&gt;
for more details.)&lt;/p&gt;
&lt;p&gt;While it can be convenient to animate layout properties, there are costs to
doing so, even if those costs aren&#39;t immediately apparent. Animations should be
defined in terms of composite property changes wherever possible.&lt;/p&gt;
&lt;p&gt;Defining &lt;a href=&quot;https://web.dev/css-vs-javascript/&quot;&gt;declarative CSS animations or using Web
Animations&lt;/a&gt;,
and ensuring you &lt;a href=&quot;https://developer.chrome.com/blog/hardware-accelerated-animations/&quot; rel=&quot;noopener&quot;&gt;animate composite
properties&lt;/a&gt;,
is a great first step to ensuring smooth and efficient animations. But still,
this alone does not guarantee smoothness because even efficient web animations
have performance limits. That&#39;s why it is always important to measure!&lt;/p&gt;
&lt;h2 id=&quot;what-are-animation-frames&quot;&gt;What are animation frames? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/smoothness/#what-are-animation-frames&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Updates to the visual representation of a page take time to appear. A visual
change will lead to a new animation frame, which is eventually rendered on the
user&#39;s display.&lt;/p&gt;
&lt;p&gt;Displays update on some interval, so visual updates are batched. Many displays
update on a fixed interval of time, such as 60 times a second (that is
60 Hz). Some more modern displays can offer higher refresh rates
(90–120 Hz are becoming common). Often these displays can actively adapt
between refresh rates as needed, or even offer fully variable frame rates.&lt;/p&gt;
&lt;p&gt;The goal for any application, like a game or a browser, is to process all these
batched visual updates and produce a visually complete animation frame within
the deadline, every time. Note that this goal is entirely distinct from other
important browser tasks such as loading content from the network quickly or
executing JavaScript tasks efficiently.&lt;/p&gt;
&lt;p&gt;At some point, it can become too difficult to complete all visual updates within
the allotted deadline assigned by the display. When this happens, the browser
&lt;strong&gt;drops a frame&lt;/strong&gt;. Your screen doesn&#39;t go black, it just repeats itself. You see
the same visual update for a bit longer—the same animation frame that was
presented at the previous frame opportunity.&lt;/p&gt;
&lt;p&gt;This actually happens often! It is not necessarily even perceptible, especially
for static or document-like content, which is common on the web platform in
particular. Dropped frames only become apparent when there are important visual
updates, such as animations, for which we need a steady stream of animation
updates to show smooth motion.&lt;/p&gt;
&lt;h2 id=&quot;what-impacts-animation-frames&quot;&gt;What impacts animation frames? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/smoothness/#what-impacts-animation-frames&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Web developers can greatly impact the ability of a browser to quickly and
efficiently render and present visual updates!&lt;/p&gt;
&lt;p&gt;Some examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Using content that is too large or resource-intensive to decode quickly on the
target device.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://web.dev/stick-to-compositor-only-properties-and-manage-layer-count/&quot;&gt;Using too many
layers&lt;/a&gt;
requiring too much GPU memory.&lt;/li&gt;
&lt;li&gt;Defining overly complex CSS styles or web animations.&lt;/li&gt;
&lt;li&gt;Using design anti-patterns that disable fast rendering optimizations.&lt;/li&gt;
&lt;li&gt;Too much JS work on the main thread, leading to long tasks that block visual
updates.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But how can you know when an animation frame has missed its deadline and caused
a dropped frame?&lt;/p&gt;
&lt;p&gt;One possible method is using
&lt;a href=&quot;https://developer.mozilla.org/docs/Web/API/window/requestAnimationFrame&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;requestAnimationFrame()&lt;/code&gt;&lt;/a&gt;
polling, however it has several downsides. &lt;code&gt;requestAnimationFrame()&lt;/code&gt;, or &amp;quot;rAF&amp;quot;,
tells the browser that you wish to perform an animation and asks for an
opportunity to do so before the next paint stage of the rendering pipeline. If
your callback function isn&#39;t called at the time you expect it, that means a
paint wasn&#39;t executed, and one or more frames were skipped. By polling and
counting how often rAF is called, you can compute a sort of &amp;quot;frames per second&amp;quot;
(FPS) metric.&lt;/p&gt;
&lt;aside class=&quot;aside flow bg-state-warn-bg color-state-warn-text&quot;&gt;&lt;p class=&quot;cluster &quot;&gt;&lt;span class=&quot;aside__icon box-block color-state-warn-text&quot;&gt;&lt;svg width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;currentColor&quot; role=&quot;img&quot; aria-label=&quot;Warning sign&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;   &lt;path fill-rule=&quot;evenodd&quot; clip-rule=&quot;evenodd&quot; d=&quot;M23 21L12 2 1 21h22zm-12-3v-2h2v2h-2zm0-4h2v-4h-2v4z&quot;&gt;&lt;/path&gt; &lt;/svg&gt;&lt;/span&gt;&lt;strong&gt;Warning&lt;/strong&gt;&lt;/p&gt;&lt;div class=&quot; flow&quot;&gt; The following code is an anti-pattern and is strongly discouraged! &lt;/div&gt;&lt;/aside&gt;
&lt;div&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; frameTimes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pollFramesPerSecond&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;  frameTimes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;frameTimes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; t &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; now &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; now&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token function&quot;&gt;requestAnimationFrame&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pollFramesPerSecond&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;Frames per second:&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; frameTimes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token function&quot;&gt;requestAnimationFrame&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pollFramesPerSecond&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;Using &lt;code&gt;requestAnimationFrame()&lt;/code&gt; polling is not a good idea for several reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Every script has to set up its own polling loop.&lt;/li&gt;
&lt;li&gt;It can block the critical path.&lt;/li&gt;
&lt;li&gt;Even if the rAF polling is fast, it can prevent
&lt;a href=&quot;https://developer.mozilla.org/docs/Web/API/window/requestIdleCallback&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;requestIdleCallback()&lt;/code&gt;&lt;/a&gt;
from being able to schedule long idle blocks when used continuously (blocks that
exceed a single frame).&lt;/li&gt;
&lt;li&gt;Similarly, lack of long idle blocks prevents the browser from scheduling other
long-running tasks (such as longer garbage collection and other background or
speculative work).&lt;/li&gt;
&lt;li&gt;If polling is toggled on and off, then you&#39;ll miss cases where frame budget
has been exceeded.&lt;/li&gt;
&lt;li&gt;Polling will report false-positives in cases where the browser is using
variable update frequency (for example, due to power or visibility status).&lt;/li&gt;
&lt;li&gt;And most importantly, it doesn&#39;t actually capture all types of animation
updates!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Too much work on the main thread can impact the ability to see animation frames.
Check out the &lt;a href=&quot;https://googlechrome.github.io/devtools-samples/jank/&quot; rel=&quot;noopener&quot;&gt;Jank
Sample&lt;/a&gt; to see how a
rAF-driven animation, once there is too much work on the main thread (such as
layout), will lead to dropped frames and fewer rAF callbacks, and lower FPS.&lt;/p&gt;
&lt;p&gt;When the main thread becomes bogged down, visual updates begin to stutter.
That&#39;s jank!&lt;/p&gt;
&lt;p&gt;Many measurement tools have focused extensively on the ability for the main
thread to yield in a timely manner, and for animation frames to run smoothly.
But this is not the whole story! Consider the following example:&lt;/p&gt;
&lt;p&gt;&lt;video autoplay=&quot;&quot; controls=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot;&gt;      &lt;source src=&quot;https://storage.googleapis.com/web-dev-uploads/video/nM10iAStORWg0YlDbPc2czmpRRr2/xkdE00Gizsks9ytPkP6r.mov&quot; type=&quot;video/mp4&quot; /&gt;    &lt;/video&gt;&lt;/p&gt;
&lt;p&gt;The video above shows a page that periodically injects long tasks onto the main
thread. These long tasks completely ruin the ability of the page to provide
certain types of visual updates, and you can see in the top-left corner a
corresponding drop of &lt;code&gt;requestAnimationFrame()&lt;/code&gt; reported FPS to 0.&lt;/p&gt;
&lt;p&gt;And yet, despite these long tasks, the page continues to scroll smoothly. This
is because on modern browsers, &lt;a href=&quot;https://blogs.windows.com/msedgedev/2017/03/08/scrolling-on-the-web/#:~:text=The%20multithreaded%20web&quot; rel=&quot;noopener&quot;&gt;scrolling is often
threaded&lt;/a&gt;,
driven entirely by the compositor.&lt;/p&gt;
&lt;p&gt;This is an example that simultaneously contains many dropped frames on the main
thread, yet still has many successfully-delivered frames of scrolling on the
compositor thread. Once the long task is complete, the main thread paint update
has no visual change to offer anyway. rAF polling suggested a frame drop to 0,
but &lt;em&gt;visually&lt;/em&gt;, a user wouldn&#39;t be able to notice a difference!&lt;/p&gt;
&lt;p&gt;For animation frames, the story is not that simple.&lt;/p&gt;
&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt; There are many reasons why long tasks are bad—and these are captured with &lt;a href=&quot;https://web.dev/custom-metrics/&quot;&gt;dedicated performance APIs&lt;/a&gt;, such as the Long Tasks API or the Event Timing API. Yet, there are also features, such as &lt;a href=&quot;https://web.dev/isinputpending/&quot;&gt;&lt;code&gt;isInputPending()&lt;/code&gt;&lt;/a&gt;, where long tasks during idle periods may be added entirely by design and be a good thing. &lt;/div&gt;&lt;/aside&gt;
&lt;h2 id=&quot;animation-frames-updates-that-matter&quot;&gt;Animation frames: Updates that matter &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/smoothness/#animation-frames-updates-that-matter&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The above example showcases that there is more to the story than just
&lt;code&gt;requestAnimationFrame()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;So when do animation updates and animation frames matter?  Here are
some criteria we&#39;re thinking about and would love to get feedback on:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Main and compositor thread updates&lt;/li&gt;
&lt;li&gt;Missing paint updates&lt;/li&gt;
&lt;li&gt;Detecting animations&lt;/li&gt;
&lt;li&gt;Quality versus quantity&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;main-and-compositor-thread-updates&quot;&gt;Main and compositor thread updates &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/smoothness/#main-and-compositor-thread-updates&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Animation frame updates are not boolean. It is not the case that frames may only
be fully dropped or fully presented. There are many reasons why an animation
frame may be &lt;em&gt;partially&lt;/em&gt; &lt;em&gt;presented&lt;/em&gt;. In other words, it can simultaneously have
&lt;em&gt;some stale content&lt;/em&gt; while also having &lt;em&gt;some new visual updates&lt;/em&gt; which are
presented.&lt;/p&gt;
&lt;p&gt;The most common example of this is when the browser is unable to produce a new
main thread update within frame deadline but does have a new compositor thread
update (such as the threaded scrolling example from earlier).&lt;/p&gt;
&lt;p&gt;One important reason why using declarative animations to animate composite
properties is recommended is that doing so enables an animation to be driven
entirely by the compositor thread even when the main thread is busy. These types
of animations can continue to produce visual updates efficiently and in
parallel.&lt;/p&gt;
&lt;p&gt;On the other hand, there may be cases where a main thread update finally becomes
available for presentation, but only after missing several frame deadlines. Here
the browser will have &lt;em&gt;some&lt;/em&gt; new update, but it may not be &lt;em&gt;the very latest&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Broadly speaking, we consider frames that contain some new visual updates,
without all new visual updates, as a &lt;em&gt;partial frame&lt;/em&gt;. Partial frames are fairly
common. Ideally, partial updates would at least include the most important
visual updates, like animations, but that can only happen if animations are
driven by the compositor thread.&lt;/p&gt;
&lt;h3 id=&quot;missing-paint-updates&quot;&gt;Missing paint updates &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/smoothness/#missing-paint-updates&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Another type of partial update is when media like images have not finished
decoding and rasterizing in time for frame presentation.&lt;/p&gt;
&lt;p&gt;Or, even if a page is perfectly static, browsers may still fall behind rendering
visual updates during rapid scrolling. That is because the pixel renditions of
content beyond the visible viewport may be discarded to save GPU memory. It
takes time to render pixels, and it may take longer than a single frame to
render everything after a large scroll, like a finger fling. This is commonly
known as &lt;em&gt;checkerboarding&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;With each frame rendering opportunity, it&#39;s possible to track how much of the
latest visual updates actually got to the screen. Measuring the ability to do so
over many frames (or time) is broadly known as &lt;em&gt;frame throughput&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;If the GPU is really bogged down, the browser (or platform) may even begin to
throttle the rate at which it attempts visual updates and thus decreases
effective frame rates. While technically that can reduce the number of dropped
frame updates, visually it will still appear as a lower frame throughput.&lt;/p&gt;
&lt;p&gt;Yet, not all types of low frame throughput are bad. If the page is mostly idle
and there are no active animations, a low frame rate is just as visually
appealing as a high frame rate (and, it can save battery!).&lt;/p&gt;
&lt;p&gt;So when does frame throughput matter?&lt;/p&gt;
&lt;h3 id=&quot;detecting-animations&quot;&gt;Detecting animations &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/smoothness/#detecting-animations&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;High frame throughput matters especially during periods with important
animations. Different animation types will depend on visual updates from a
specific thread (main, compositor, or a worker), so its visual update is
dependent on that thread providing its update within the deadline. We say that a
given thread &lt;em&gt;affects smoothness&lt;/em&gt; whenever there is an active animation that
depends on that thread update.&lt;/p&gt;
&lt;p&gt;Some types of animations are easier to define and detect than others.
Declarative animations, or user-input-driven animations, are clearer to define
than JavaScript-driven animations implemented as periodic updates to animatable
style properties.&lt;/p&gt;
&lt;p&gt;Even with &lt;code&gt;requestAnimationFrame()&lt;/code&gt; you
cannot always assume that every rAF call is necessarily producing a visual
update or animation. For example, using rAF polling just to track frame rate
(as shown above) should not itself affect smoothness measurements since there is
no visual update.&lt;/p&gt;
&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt; Animation detection in tooling, as well as the specifics of animation implementations in browsers, continually evolves and improves. Chrome recently moved &lt;a href=&quot;https://developer.chrome.com/blog/hardware-accelerated-animations/#whats-coming-next&quot;&gt;background-color animations&lt;/a&gt; from the main thread to the compositor! &lt;/div&gt;&lt;/aside&gt;
&lt;h3 id=&quot;quality-versus-quantity&quot;&gt;Quality versus quantity &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/smoothness/#quality-versus-quantity&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Finally, detecting animations and animation frame updates is still only part of
the story because it only captures the quantity of animation updates, not the
quality.&lt;/p&gt;
&lt;p&gt;For example, you may see a steady framerate of of 60 fps while watching a
video. Technically, this is perfectly smooth, but the video itself may have a
low bit rate, or issues with network buffering. This isn&#39;t captured by
animation smoothness metrics directly, yet may still be jarring to the
user.&lt;/p&gt;
&lt;p&gt;Or, a game which leverages &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; (perhaps even using techniques like
&lt;a href=&quot;https://developer.chrome.com/blog/offscreen-canvas/&quot; rel=&quot;noopener&quot;&gt;offscreen
canvas&lt;/a&gt; to
ensure a steady frame rate) may technically be perfectly smooth in terms of
animation frames, all while failing to load high quality game assets into the
scene or exhibiting rendering artifacts.&lt;/p&gt;
&lt;p&gt;And of course, a site can just have some really bad animations 🙂&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://upload.wikimedia.org/wikipedia/commons/1/1c/Under-Construction-Bulldozer.gif&quot; alt=&quot;Old school under construction GIF&quot; width=&quot;410&quot; height=&quot;49&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I mean, I guess they were pretty cool for their time!&lt;/p&gt;
&lt;h2 id=&quot;states-of-a-single-animation-frame&quot;&gt;States of a single animation frame &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/smoothness/#states-of-a-single-animation-frame&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Because frames may be partially presented, or dropped frames may happen in ways
that do not affect smoothness, we have begun to think of each frame as having a
completeness or smoothness score.&lt;/p&gt;
&lt;p&gt;Here is the spectrum of ways in which we interpret the state of a single
animation frame, ordered from best to worst case:&lt;/p&gt;
&lt;div&gt;
  &lt;table&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;No Update Desired&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Idle time, repeat of the previous frame.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Fully presented&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;The main thread update was either committed within deadline, or no
      main thread update was desired.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Partially presented&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Compositor only; the delayed main thread update had no visual
      change.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Partially presented&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Compositor only; the main thread had a visual update, but that
      update did not include an animation that affects smoothness.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Partially presented&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Compositor only; the main thread had a visual update that affects
      smoothness, but a previously stale frame arrived and was used instead.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Partially presented&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Compositor only; without the desired main update, and the
      compositor update has an animation that affects smoothness.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Partially presented&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Compositor only but the compositor update does not have an
      animation that affects smoothness.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Dropped frame&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;No update. There was no compositor update desired, and main was
      delayed.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Dropped frame&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;A compositor update was desired, but it was delayed.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Stale frame&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;An update was desired, it was produced by the renderer, but the
      GPU still did not present it before the vsync deadline.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;It&#39;s possible to turn these states into somewhat of a score. And perhaps one way
to interpret this score is to consider it a &lt;em&gt;probability&lt;/em&gt; of being observable by
the user. A single dropped frame may not be very observable, but a sequence of
many dropped frames affecting smoothness in a row sure is!&lt;/p&gt;
&lt;h2 id=&quot;putting-it-all-together-a-percent-dropped-frames-metric&quot;&gt;Putting it all together: A Percent Dropped Frames metric &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/smoothness/#putting-it-all-together-a-percent-dropped-frames-metric&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;While it can sometimes be necessary to dive deep into the state of each
animation frame, it&#39;s also useful to just assign a quick &amp;quot;at a glance&amp;quot; score for
an experience.&lt;/p&gt;
&lt;p&gt;Because frames may be &lt;em&gt;partially presented,&lt;/em&gt; and because even fully skipped
frame updates may not actually &lt;em&gt;affect smoothness&lt;/em&gt;, we want to focus less on
just counting frames, and more on the &lt;em&gt;extent&lt;/em&gt; to which the browser is unable to
provide &lt;em&gt;visually complete&lt;/em&gt; updates &lt;em&gt;when it mattered&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The mental model should move from:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Frames Per Second&lt;/em&gt;, to&lt;/li&gt;
&lt;li&gt;Detecting missing and important animation updates, to&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Percentage Dropped&lt;/em&gt; over a given time period.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;What matters is: &lt;em&gt;the proportion of time waiting for important
updates&lt;/em&gt;. We think this matches the natural way users experience the smoothness
of web content in practice. So far, we have been using the following as an
initial set of metrics:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Average Percent Dropped:&lt;/strong&gt; for all non-idle animation frames throughout the
whole timeline&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Worst Case of Percent Dropped Frames:&lt;/strong&gt; as measured over 1 second sliding
windows of time.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;95th percentile of Percent Dropped Frames:&lt;/strong&gt; as measured over 1 second
sliding windows of time.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can find these scores in some Chrome developer tools today. While these
metrics focus only on overall frame throughput, we are also evaluating other
factors, such as frame latency.&lt;/p&gt;
&lt;aside class=&quot;aside flow bg-state-info-bg color-state-info-text&quot;&gt;&lt;div class=&quot; flow&quot;&gt; These names are somewhat historical. The &amp;quot;Percent Dropped&amp;quot; naming no longer matches any literal &amp;quot;was a frame dropped&amp;quot; concept. As the previous section covered, each animation frame is a complicated arrangement of conditions leading to an overall probability. Expect these names to evolve over time. &lt;/div&gt;&lt;/aside&gt;
&lt;h2 id=&quot;try-it-yourself-in-developer-tooling&quot;&gt;Try it yourself in developer tooling! &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/smoothness/#try-it-yourself-in-developer-tooling&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;performance-hud&quot;&gt;Performance HUD &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/smoothness/#performance-hud&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Chromium has a neat Performance HUD hidden behind a flag
(&lt;code&gt;chrome://flags/#show-performance-metrics-hud&lt;/code&gt;). In it, you can find live
scores for things like Core Web Vitals and also a few experimental definitions
for animation smoothness based on &lt;em&gt;Percent Dropped Frames&lt;/em&gt; over time.&lt;/p&gt;
&lt;img alt=&quot;Performance HUD&quot; decoding=&quot;async&quot; height=&quot;441&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/hblBG5oYxWsUOua0tW3C.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/hblBG5oYxWsUOua0tW3C.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/hblBG5oYxWsUOua0tW3C.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/hblBG5oYxWsUOua0tW3C.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/hblBG5oYxWsUOua0tW3C.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/hblBG5oYxWsUOua0tW3C.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/hblBG5oYxWsUOua0tW3C.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/hblBG5oYxWsUOua0tW3C.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/hblBG5oYxWsUOua0tW3C.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/hblBG5oYxWsUOua0tW3C.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/hblBG5oYxWsUOua0tW3C.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/hblBG5oYxWsUOua0tW3C.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/hblBG5oYxWsUOua0tW3C.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/hblBG5oYxWsUOua0tW3C.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/hblBG5oYxWsUOua0tW3C.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/hblBG5oYxWsUOua0tW3C.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/hblBG5oYxWsUOua0tW3C.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/hblBG5oYxWsUOua0tW3C.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;h3 id=&quot;frame-rendering-stats&quot;&gt;Frame Rendering Stats &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/smoothness/#frame-rendering-stats&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/evaluate-performance/reference/#fps-meter&quot; rel=&quot;noopener&quot;&gt;Enable &amp;quot;Frame Rendering
Stats&amp;quot;&lt;/a&gt;
in DevTools via Rendering settings to see a live view of new animation frames,
which are color-coded to differentiate partial updates from fully-dropped frame
updates. The reported fps is for fully-presented frames only.&lt;/p&gt;
&lt;img alt=&quot;Frame rendering stats&quot; decoding=&quot;async&quot; height=&quot;372&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 398px) 398px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/xazCKFNCWwjviBGS9JO6.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/xazCKFNCWwjviBGS9JO6.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/xazCKFNCWwjviBGS9JO6.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/xazCKFNCWwjviBGS9JO6.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/xazCKFNCWwjviBGS9JO6.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/xazCKFNCWwjviBGS9JO6.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/xazCKFNCWwjviBGS9JO6.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/xazCKFNCWwjviBGS9JO6.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/xazCKFNCWwjviBGS9JO6.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/xazCKFNCWwjviBGS9JO6.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/xazCKFNCWwjviBGS9JO6.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/xazCKFNCWwjviBGS9JO6.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/xazCKFNCWwjviBGS9JO6.png?auto=format&amp;w=796 796w&quot; width=&quot;398&quot; /&gt;
&lt;h3 id=&quot;frame-viewer-in-devtools-performance-profile-recordings&quot;&gt;Frame Viewer in DevTools performance profile recordings &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/smoothness/#frame-viewer-in-devtools-performance-profile-recordings&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;a href=&quot;https://developer.chrome.com/docs/devtools/evaluate-performance/&quot; rel=&quot;noopener&quot;&gt;DevTools Performance
panel&lt;/a&gt; has
long had a &lt;a href=&quot;https://developer.chrome.com/docs/devtools/evaluate-performance/reference/#frames&quot; rel=&quot;noopener&quot;&gt;Frames
viewer&lt;/a&gt;.
However, it had grown a bit out of sync with how the modern rendering pipeline
actually works. There has been plenty of recent improvement, even in the latest
Chrome Canary, which we think will greatly ease debugging animation issues.&lt;/p&gt;
&lt;p&gt;Today you will find that frames in the frames viewer are better aligned with
vsync boundaries, and color-coded based on status. There is still not full
visualization for all the nuances outlined above, but we&#39;re planning to add more
in the near future.&lt;/p&gt;
&lt;img alt=&quot;Frame viewer in Chrome DevTools&quot; decoding=&quot;async&quot; height=&quot;148&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/nM10iAStORWg0YlDbPc2czmpRRr2/ou89sgoFeg2481KVUWmF.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/nM10iAStORWg0YlDbPc2czmpRRr2/ou89sgoFeg2481KVUWmF.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/nM10iAStORWg0YlDbPc2czmpRRr2/ou89sgoFeg2481KVUWmF.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/nM10iAStORWg0YlDbPc2czmpRRr2/ou89sgoFeg2481KVUWmF.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/nM10iAStORWg0YlDbPc2czmpRRr2/ou89sgoFeg2481KVUWmF.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/nM10iAStORWg0YlDbPc2czmpRRr2/ou89sgoFeg2481KVUWmF.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/nM10iAStORWg0YlDbPc2czmpRRr2/ou89sgoFeg2481KVUWmF.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/nM10iAStORWg0YlDbPc2czmpRRr2/ou89sgoFeg2481KVUWmF.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/nM10iAStORWg0YlDbPc2czmpRRr2/ou89sgoFeg2481KVUWmF.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/nM10iAStORWg0YlDbPc2czmpRRr2/ou89sgoFeg2481KVUWmF.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/nM10iAStORWg0YlDbPc2czmpRRr2/ou89sgoFeg2481KVUWmF.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/nM10iAStORWg0YlDbPc2czmpRRr2/ou89sgoFeg2481KVUWmF.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/nM10iAStORWg0YlDbPc2czmpRRr2/ou89sgoFeg2481KVUWmF.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/nM10iAStORWg0YlDbPc2czmpRRr2/ou89sgoFeg2481KVUWmF.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/nM10iAStORWg0YlDbPc2czmpRRr2/ou89sgoFeg2481KVUWmF.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/nM10iAStORWg0YlDbPc2czmpRRr2/ou89sgoFeg2481KVUWmF.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/nM10iAStORWg0YlDbPc2czmpRRr2/ou89sgoFeg2481KVUWmF.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/nM10iAStORWg0YlDbPc2czmpRRr2/ou89sgoFeg2481KVUWmF.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;h3 id=&quot;chrome-tracing&quot;&gt;Chrome tracing &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/smoothness/#chrome-tracing&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Finally, with Chrome Tracing, the tool of choice for diving deep into details,
you can record a &amp;quot;Web content rendering&amp;quot; trace via the new &lt;a href=&quot;https://ui.perfetto.dev/&quot; rel=&quot;noopener&quot;&gt;Perfetto
UI&lt;/a&gt; (or &lt;code&gt;about:tracing&lt;/code&gt;), and dig deep into Chrome&#39;s
graphics pipeline. It can be a daunting task, but there are a few things
recently added to Chromium to make it easier. You can get an overview of what is
available in the &lt;a href=&quot;https://chromium.googlesource.com/chromium/src/+/HEAD/docs/life_of_a_frame.md&quot; rel=&quot;noopener&quot;&gt;Life of a
Frame&lt;/a&gt;
document.&lt;/p&gt;
&lt;p&gt;Through trace events you can definitively determine:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Which animations are running (using events named &lt;code&gt;TrackerValidation&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Getting the exact timeline of animation frames (using events named
&lt;code&gt;PipelineReporter&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;For janky animation updates, figure out exactly what is blocking your
animation from running faster (using the event breakdowns within
&lt;code&gt;PipelineReporter&lt;/code&gt; events).&lt;/li&gt;
&lt;li&gt;For input-driven animations, see how long it takes to get a visual update
(using events named &lt;code&gt;EventLatency&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;img alt=&quot;Chrome Tracing pipeline reporter&quot; decoding=&quot;async&quot; height=&quot;138&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/O0vDMhhaob9bllU0xRVy.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/O0vDMhhaob9bllU0xRVy.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/O0vDMhhaob9bllU0xRVy.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/O0vDMhhaob9bllU0xRVy.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/O0vDMhhaob9bllU0xRVy.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/O0vDMhhaob9bllU0xRVy.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/O0vDMhhaob9bllU0xRVy.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/O0vDMhhaob9bllU0xRVy.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/O0vDMhhaob9bllU0xRVy.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/O0vDMhhaob9bllU0xRVy.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/O0vDMhhaob9bllU0xRVy.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/O0vDMhhaob9bllU0xRVy.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/O0vDMhhaob9bllU0xRVy.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/O0vDMhhaob9bllU0xRVy.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/O0vDMhhaob9bllU0xRVy.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/O0vDMhhaob9bllU0xRVy.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/O0vDMhhaob9bllU0xRVy.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/eqprBhZUGfb8WYnumQ9ljAxRrA72/O0vDMhhaob9bllU0xRVy.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
&lt;h2 id=&quot;whats-next&quot;&gt;What&#39;s next &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/smoothness/#whats-next&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&quot;https://web.dev/vitals/&quot;&gt;Web Vitals&lt;/a&gt; initiative aims to provide metric and guidance for
building great user experiences on the web.
&lt;a href=&quot;https://web.dev/user-centric-performance-metrics/#in-the-lab&quot;&gt;Lab-based&lt;/a&gt; metrics like &lt;a href=&quot;https://web.dev/tbt/&quot;&gt;Total
Blocking Time (TBT)&lt;/a&gt; and &lt;a href=&quot;https://web.dev/tti/&quot;&gt;Time to Interactive (TTI)&lt;/a&gt; are vital for
catching and diagnosing potential interactivity issues. We are planning to
design a similar lab-based metric for animation smoothness.&lt;/p&gt;
&lt;p&gt;We&#39;ll keep you posted as we continue to work through ideas for designing a
comprehensive metric based on individual animation frame data.&lt;/p&gt;
&lt;p&gt;In the future, we&#39;d also like to design APIs that make it possible to measure
animation smoothness performantly for real users in the
&lt;a href=&quot;https://web.dev/user-centric-performance-metrics/#in-the-field&quot;&gt;field&lt;/a&gt; as well as in the lab.
Stay tuned for updates there as well!&lt;/p&gt;
&lt;h2 id=&quot;feedback&quot;&gt;Feedback &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/smoothness/#feedback&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We&#39;re excited about all the recent improvements and developer tools that have
shipped in Chrome to measure animation smoothness. Please try these tools out,
benchmark your animations, and let us know where it leads!&lt;/p&gt;
&lt;p&gt;You can send your comments to the
&lt;a href=&quot;https://groups.google.com/g/web-vitals-feedback&quot; rel=&quot;noopener&quot;&gt;web-vitals-feedback&lt;/a&gt; Google
group with &amp;quot;[Smoothness Metrics]&amp;quot; in the subject line. We&#39;re really looking
forward to hearing what you think!&lt;/p&gt;
</content>
    <author>
      <name>Michal Mocny</name>
    </author><author>
      <name>Behdad Bakhshinategh</name>
    </author><author>
      <name>Jonathan Ross</name>
    </author>
  </entry>
  
  <entry>
    <title>Feedback wanted: The road to a better layout shift metric for long-lived pages</title>
    <link href="https://web.dev/better-layout-shift-metric/"/>
    <updated>2021-01-25T00:00:00Z</updated>
    <id>https://web.dev/better-layout-shift-metric/</id>
    <content type="html" mode="escaped">&lt;p&gt;&lt;a href=&quot;https://web.dev/cls&quot;&gt;Cumulative Layout Shift&lt;/a&gt; (CLS) is a metric that measures the visual stability of a web page. The metric is called cumulative layout shift because the score of every individual shift is summed throughout the lifespan of the page.&lt;/p&gt;
&lt;p&gt;While all layout shifts are poor user experiences, they do add up more on pages that are open longer. That&#39;s why the Chrome Speed Metrics Team set out to improve the CLS metric to be more neutral to the time spent on a page.&lt;/p&gt;
&lt;p&gt;It&#39;s important that the metric focuses on user experience through the full page lifetime, as we&#39;ve found that users often have negative experiences after load, while scrolling or navigating through pages. But we&#39;ve heard concerns about how this impacts long-lived pages—pages which the user generally has open for a long time. There are several different types of pages which tend to stay open longer; some of the most common are social media apps with infinite scroll and single-page applications.&lt;/p&gt;
&lt;p&gt;An internal analysis of long-lived pages with high CLS scores found that most problems were caused by the following patterns:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://addyosmani.com/blog/infinite-scroll-without-layout-shifts/&quot; rel=&quot;noopener&quot;&gt;Infinite scrollers shifting content&lt;/a&gt; as the user scrolls.&lt;/li&gt;
&lt;li&gt;Input handlers taking longer than 500 ms to update the UI in response to a user interaction, without any kind of placeholder or skeleton pattern.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;While we encourage developers to improve those user experiences, we&#39;re also working towards improving the metric and looking for feedback on possible approaches.&lt;/p&gt;
&lt;h2 id=&quot;how-would-we-decide-if-a-new-metric-is-better&quot;&gt;How would we decide if a new metric is better? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/better-layout-shift-metric/#how-would-we-decide-if-a-new-metric-is-better&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before diving into metric design, we wanted to ensure that we evaluated our ideas on a wide variety of real-world web pages and use cases. To start, we designed a small user study.&lt;/p&gt;
&lt;p&gt;First, we recorded videos and &lt;a href=&quot;https://www.chromium.org/developers/how-tos/trace-event-profiling-tool&quot; rel=&quot;noopener&quot;&gt;Chrome traces&lt;/a&gt; of 34 user journeys through various websites. In selecting the user journeys, we aimed for a few things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A variety of different types of sites, such as news and shopping sites.&lt;/li&gt;
&lt;li&gt;A variety of user journeys, such as initial page load, scrolling, single-page app navigations, and user interactions.&lt;/li&gt;
&lt;li&gt;A variety of both number and intensity of individual layout shifts on the sites.&lt;/li&gt;
&lt;li&gt;Few negative experiences on the sites apart from layout shifts.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We asked 41 of our colleagues to watch two videos at a time, rating which of the pair was better in terms of layout shift. From these ratings, we created an idealized ranking order of the sites. The results of the user ranking confirmed our suspicions that our colleagues, like most users, are really frustrated by layout shifts after load, especially during scrolling and single-page app navigations. We saw that some sites have much better user experiences during these activities than others.&lt;/p&gt;
&lt;p&gt;Since we recorded Chrome traces along with the videos, we had all the details of the individual layout shifts in each user journey. We used those to compute metric values for each idea for each user journey. This allowed us to see how each metric variant ranked the user journeys, and how different each was from the ideal ranking.&lt;/p&gt;
&lt;h2 id=&quot;what-metric-ideas-did-we-test&quot;&gt;What metric ideas did we test? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/better-layout-shift-metric/#what-metric-ideas-did-we-test&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;windowing-strategies&quot;&gt;Windowing strategies &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/better-layout-shift-metric/#windowing-strategies&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Often pages have multiple layout shifts bunched closely together, because elements can shift multiple times as new content comes in piece by piece. This prompted us to try out techniques for grouping shifts together. To accomplish that, we looked at three windowing approaches:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tumbling windows&lt;/li&gt;
&lt;li&gt;Sliding windows&lt;/li&gt;
&lt;li&gt;Session windows&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In each of these examples, the page has layout shifts of varying severity over time. Each blue bar represents a single layout shift, and the length represents the &lt;a href=&quot;https://web.dev/cls/#layout-shift-score&quot;&gt;score&lt;/a&gt; of that shift. The images illustrate the ways different windowing strategies group the layout shifts over time.&lt;/p&gt;
&lt;h4 id=&quot;tumbling-windows&quot;&gt;Tumbling windows &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/better-layout-shift-metric/#tumbling-windows&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;figure&gt;
  &lt;video controls=&quot;&quot; autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot;&gt;
    &lt;source src=&quot;https://storage.googleapis.com/web-dev-assets/better-layout-shift-metric/tumbling-window.webm&quot; type=&quot;video/webm&quot; /&gt;
    &lt;source src=&quot;https://storage.googleapis.com/web-dev-assets/better-layout-shift-metric/tumbling-window.mp4&quot; type=&quot;video/mp4&quot; /&gt;
  &lt;/video&gt;
  &lt;figcaption&gt;
    Example of a tumbling window.
  &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The simplest approach is just to break the page into windows of equal-sized chunks. These are called tumbling windows. You&#39;ll notice above that the fourth bar really looks like it should be grouped into the second tumbling window, but because the windows are all a fixed size it is in the first window instead. If there are slight differences in timing of loads or user interactions on the page, the same layout shifts might fall on different sides of the tumbling window boundaries.&lt;/p&gt;
&lt;h4 id=&quot;sliding-windows&quot;&gt;Sliding windows &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/better-layout-shift-metric/#sliding-windows&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;figure&gt;
  &lt;video controls=&quot;&quot; autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot;&gt;
    &lt;source src=&quot;https://storage.googleapis.com/web-dev-assets/better-layout-shift-metric/sliding-window.webm&quot; type=&quot;video/webm&quot; /&gt;
    &lt;source src=&quot;https://storage.googleapis.com/web-dev-assets/better-layout-shift-metric/sliding-window.mp4&quot; type=&quot;video/mp4&quot; /&gt;
  &lt;/video&gt;
  &lt;figcaption&gt;
    Example of a sliding window.
  &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;An approach that lets us see more possible groupings of the same length is to continuously update the potential window over time. The image above shows one sliding window at a time, but we could look at all possible sliding windows or a subset of them to create a metric.&lt;/p&gt;
&lt;h4 id=&quot;session-windows&quot;&gt;Session windows &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/better-layout-shift-metric/#session-windows&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;figure&gt;
  &lt;video controls=&quot;&quot; autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot;&gt;
    &lt;source src=&quot;https://storage.googleapis.com/web-dev-assets/better-layout-shift-metric/session-window.webm&quot; type=&quot;video/webm&quot; /&gt;
    &lt;source src=&quot;https://storage.googleapis.com/web-dev-assets/better-layout-shift-metric/session-window.mp4&quot; type=&quot;video/mp4&quot; /&gt;
  &lt;/video&gt;
  &lt;figcaption&gt;
    Example of a session window.
  &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;If we wanted to focus on identifying areas of the page with bursts of layout shifts, we could start each window at a shift, and keep growing it until we encountered a gap of a given size between layout shifts. This approach groups the layout shifts together, and ignores most of the non-shifting user experience. One potential problem is that if there are no gaps in the layout shifts, a metric based on session windows could grow unbounded just like the current CLS metric. So we tried this out with a maximum window size as well.&lt;/p&gt;
&lt;h3 id=&quot;window-sizes&quot;&gt;Window sizes &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/better-layout-shift-metric/#window-sizes&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The metric might give very different results depending on how big the windows actually are, so we tried multiple different window sizes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Each shift as its own window (no windows)&lt;/li&gt;
&lt;li&gt;100 ms&lt;/li&gt;
&lt;li&gt;300 ms&lt;/li&gt;
&lt;li&gt;1 second&lt;/li&gt;
&lt;li&gt;5 seconds&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;summarization&quot;&gt;Summarization &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/better-layout-shift-metric/#summarization&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;We tried out many ways to summarize the different windows.&lt;/p&gt;
&lt;h4 id=&quot;percentiles&quot;&gt;Percentiles &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/better-layout-shift-metric/#percentiles&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;We looked at the maximum window value, as well as the 95th percentile, 75th percentile, and median.&lt;/p&gt;
&lt;h4 id=&quot;average&quot;&gt;Average &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/better-layout-shift-metric/#average&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;We looked at the mean window value.&lt;/p&gt;
&lt;h4 id=&quot;budgets&quot;&gt;Budgets &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/better-layout-shift-metric/#budgets&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;We wondered if maybe there was some minimum layout shift score that users wouldn&#39;t notice, and we could just count layout shifts over that &amp;quot;budget&amp;quot; in the score. So for various potential &amp;quot;budget&amp;quot; values, we looked at the percentage of shifts over budget, and the total shift score over budget.&lt;/p&gt;
&lt;h3 id=&quot;other-strategies&quot;&gt;Other strategies &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/better-layout-shift-metric/#other-strategies&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;We also looked at many strategies that didn&#39;t involve windows, like the total layout shift divided by time on page, and the average of the worst N individual shifts.&lt;/p&gt;
&lt;h2 id=&quot;the-initial-results&quot;&gt;The initial results &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/better-layout-shift-metric/#the-initial-results&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Overall, we tested &lt;strong&gt;145 different metric definitions&lt;/strong&gt; based on permutations of the above ideas. For each metric, we ranked all the user journeys by their score on the metric, and then ranked the metrics by how close they were to the ideal ranking.&lt;/p&gt;
&lt;p&gt;To get a baseline, we also ranked all the sites by their current CLS score. CLS placed 32nd, tied with 13 other strategies, so it was better than most permutations of the strategies above. To ensure the results were meaningful, we also added in three random orderings. As expected, the random orderings did worse than every strategy tested.&lt;/p&gt;
&lt;p&gt;To understand if we might be overfitting for the data set, after our analysis we recorded some new layout shift videos and traces, manually ranked those, and saw that the metric rankings were very similar for the new data set and the original one.&lt;/p&gt;
&lt;p&gt;A few different strategies stood out in the rankings.&lt;/p&gt;
&lt;h3 id=&quot;best-strategies&quot;&gt;Best strategies &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/better-layout-shift-metric/#best-strategies&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;When we ranked the strategies, we found that three types of strategies topped the list. Each had roughly the same performance, so we plan to move forward with a deeper analysis on all three. We&#39;d also like to hear developer feedback to understand if there are factors outside of user experience we should be considering when deciding between them. (See below for how to give feedback.)&lt;/p&gt;
&lt;h4 id=&quot;high-percentiles-of-long-windows&quot;&gt;High percentiles of long windows &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/better-layout-shift-metric/#high-percentiles-of-long-windows&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;A few windowing strategies worked well with long window sizes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1 second sliding windows&lt;/li&gt;
&lt;li&gt;Session windows capped at 5 seconds with 1 second gap&lt;/li&gt;
&lt;li&gt;Session windows uncapped with 1 second gap&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These all ranked really well at both the 95th percentile and the maximum.&lt;/p&gt;
&lt;p&gt;But for such large window sizes, we were concerned about using the 95th percentile—often we were looking at only 4-6 windows, and taking the 95th percentile of that is a lot of interpolation. It&#39;s unclear what the interpolation is doing in terms of the metric value. The maximum value is a lot clearer, so we decided to move forward with checking the maximum.&lt;/p&gt;
&lt;h4 id=&quot;average-of-session-windows-with-long-gaps&quot;&gt;Average of session windows with long gaps &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/better-layout-shift-metric/#average-of-session-windows-with-long-gaps&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Averaging the scores of all uncapped session windows with 5 second gaps between them performed really well. This strategy has a few interesting characteristics:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If the page doesn&#39;t have gaps between layout shifts, it ends up being one long session window with the exact same score as the current CLS.&lt;/li&gt;
&lt;li&gt;This metric didn&#39;t take idle time into account directly; it only looked at the shifts that happened on the page, and not at points in time when the page was not shifting.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;high-percentiles-of-short-windows&quot;&gt;High percentiles of short windows &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/better-layout-shift-metric/#high-percentiles-of-short-windows&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;The maximum 300 ms sliding window ranked very highly, as well as the 95th percentile. For the shorter window size, there is less percentile interpolation than larger window sizes, but we were also concerned about &amp;quot;repeat&amp;quot; sliding windows—if a set of layout shifts occurs over two frames, there are multiple 300 ms windows that include them. Taking the maximum is much clearer and simpler than taking the 95th percentile one. So again we decided to move forward with checking the maximum.&lt;/p&gt;
&lt;h3 id=&quot;strategies-that-didnt-work-out&quot;&gt;Strategies that didn&#39;t work out &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/better-layout-shift-metric/#strategies-that-didnt-work-out&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Strategies that tried to look at the &amp;quot;average&amp;quot; experience of time spent both without layout shifts and with layout shifts did very poorly. None of the median or 75th percentile summaries of any windowing strategy ranked the sites well. Neither did the sum of layout shifts over time.&lt;/p&gt;
&lt;p&gt;We evaluated a number of different &amp;quot;budgets&amp;quot; for acceptable layout shifts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Percent of layout shifts above some budget. For various budgets, these all ranked quite poorly.&lt;/li&gt;
&lt;li&gt;Average layout shift above some excess. Most variations on this strategy did poorly, but average excess over a long session with a large gap did almost as well as the average of session windows with long gaps. We decided to move forward with only the latter because it is simpler.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;next-steps&quot;&gt;Next steps &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/better-layout-shift-metric/#next-steps&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;larger-scale-analysis&quot;&gt;Larger-scale analysis &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/better-layout-shift-metric/#larger-scale-analysis&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;We&#39;ve implemented the top strategies listed above in Chrome, so that we can get data on real-world usage for a much larger set of websites. We plan to use a similar approach of ranking sites based on their metric scores to do the larger-scale analysis:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Rank all the sites by CLS, and by each new metric candidate.
&lt;ul&gt;
&lt;li&gt;Which sites are ranked most differently by CLS and each candidate? Do we find anything unexpected when we look at these sites?&lt;/li&gt;
&lt;li&gt;What are the largest differences between the new metric candidates? Do any of the differences stand out as advantages or disadvantages of a specific candidate?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Repeat the above analysis, but bucketing by time spent on each page load. Do we see an expected improvement for long-lived page loads with acceptable layout shift? Do we see any unexpected results for short-lived pages?&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;feedback-on-our-approach&quot;&gt;Feedback on our approach &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/better-layout-shift-metric/#feedback-on-our-approach&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;We&#39;d love to get feedback from web developers on these approaches. Some things to keep in mind while considering the new approaches:&lt;/p&gt;
&lt;h4 id=&quot;whats-not-changing&quot;&gt;What&#39;s not changing &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/better-layout-shift-metric/#whats-not-changing&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;We do want to clarify that a lot of things will not be changing with a new approach:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;None of our metric ideas change the way layout shift scores for &lt;a href=&quot;https://web.dev/cls/#layout-shift-score&quot;&gt;individual frames are calculated&lt;/a&gt;, only the way we summarize multiple frames. This means that the &lt;a href=&quot;https://web.dev/cls/#measure-cls-in-javascript&quot;&gt;JavaScript API&lt;/a&gt; for layout shifts will stay the same, and the underlying events in Chrome traces that developer tools use will also stay the same, so layout shift rects in tools like WebPageTest and Chrome DevTools will continue to work the same way.&lt;/li&gt;
&lt;li&gt;We&#39;ll continue to work hard on making the metrics easy for developers to adopt, including them in the &lt;a href=&quot;https://github.com/GoogleChrome/web-vitals&quot; rel=&quot;noopener&quot;&gt;web-vitals library&lt;/a&gt;, documenting on &lt;a href=&quot;https://web.dev/metrics&quot;&gt;web.dev&lt;/a&gt;, and reporting them in our developer tooling like Lighthouse.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;trade-offs-between-metrics&quot;&gt;Trade-offs between metrics &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/better-layout-shift-metric/#trade-offs-between-metrics&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;One of the top strategies summarizes the layout shift windows as an average, and the rest report the maximum window. For pages which are open a very long time, the average will likely report a more representative value, but in general it will likely be easier for developers to act on a single window—they can log when it occurred, the elements that shifted, and so on. We&#39;d love feedback on which is more important to developers.&lt;/p&gt;
&lt;p&gt;Do you find sliding or session windows easier to understand? Are the differences important to you?&lt;/p&gt;
&lt;h4 id=&quot;how-to-give-feedback&quot;&gt;How to give feedback &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/better-layout-shift-metric/#how-to-give-feedback&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;You can try out the new layout shift metrics on any site using our &lt;a href=&quot;https://github.com/mmocny/web-vitals/wiki/Snippets-for-LSN-using-PerformanceObserver&quot; rel=&quot;noopener&quot;&gt;example JavaScript implementations&lt;/a&gt; or our &lt;a href=&quot;https://github.com/mmocny/web-vitals-extension/tree/experimental-ls&quot; rel=&quot;noopener&quot;&gt;fork of the Core Web Vitals extension&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Please email feedback to our &lt;strong&gt;&lt;a href=&quot;https://groups.google.com/g/web-vitals-feedback&quot; rel=&quot;noopener&quot;&gt;web-vitals-feedback&lt;/a&gt;&lt;/strong&gt; Google group, with &amp;quot;[Layout Shift Metrics]&amp;quot; in the subject line. We&#39;re really looking forward to hearing what you think!&lt;/p&gt;
</content>
    <author>
      <name>Annie Sullivan</name>
    </author><author>
      <name>Michal Mocny</name>
    </author>
  </entry>
</feed>
