<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>https://web.dev/</id>
  <title>Brendan Kenny on web.dev</title>
  <updated>2026-04-15T23:21:06Z</updated>
  <author>
    <name>Brendan Kenny</name>
  </author>
  <link href="https://web.dev/authors/bckenny/feed.xml" rel="self"/>
  <link href="https://web.dev/"/>
  <icon>https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/sWOfAs4f2WyQMMF9xt1A.jpg?auto=format</icon>
  <logo>https://web.dev/images/shared/rss-banner.png</logo>
  <subtitle>Lighthouse lens polisher</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>Our top Core Web Vitals recommendations for 2023</title>
    <link href="https://web.dev/top-cwv-2023/"/>
    <updated>2023-01-10T00:00:00Z</updated>
    <id>https://web.dev/top-cwv-2023/</id>
    <content type="html" mode="escaped">&lt;p&gt;Over the years, we at Google have made a lot of recommendations to web developers on how to improve performance.&lt;/p&gt;
&lt;p&gt;While each of these recommendations, individually, may improve performance for many sites, the full set of recommendations is admittedly overwhelming and, realistically, there&#39;s no way any one person or site could follow all of them.&lt;/p&gt;
&lt;p&gt;Unless web performance is your day job, it&#39;s probably not obvious which recommendations are going to have the largest positive impact on your site. For example, you might have read that implementing critical CSS can improve load performance, and you may have also heard that it&#39;s important to optimize your images. But, if you don&#39;t have time to work on both things, how would you decide which one to pick?&lt;/p&gt;
&lt;p&gt;On the Chrome team, we&#39;ve spent the last year trying to answer this question: &lt;em&gt;what are the most important recommendations we can give to developers to help them improve performance for their users?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;To adequately answer this question we have to consider not just the technical merits of any given recommendation, but also human and organizational factors that influence the likelihood that developers will actually be able to adopt these recommendations. In other words, some recommendations may be hugely impactful in theory, but in reality very few sites will have the time or resources to implement them. Similarly, some recommendations are critical, but most websites are already following these practices.&lt;/p&gt;
&lt;p&gt;In short, we wanted our list of top web performance recommendations to focus on:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Recommendations we believe will have the &lt;strong&gt;largest real-world impact&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Recommendations that are &lt;strong&gt;relevant and applicable to most sites&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Recommendations that are &lt;strong&gt;realistic for most developers to implement&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Over the past year we&#39;ve spent a lot of time auditing the full set of performance recommendations we make, and assessing each of them (both qualitatively and quantitatively) against the above three criteria.&lt;/p&gt;
&lt;p&gt;This post outlines our top recommendations to improve performance for each of the &lt;a href=&quot;https://web.dev/vitals/#core-web-vitals&quot;&gt;Core Web Vitals&lt;/a&gt; metrics. If you&#39;re new to web performance, or if you&#39;re trying to decide what will give you the biggest bang for your buck, we think these recommendations are the best place to start.&lt;/p&gt;
&lt;h2 id=&quot;largest-contentful-paint-lcp&quot;&gt;Largest Contentful Paint (LCP) &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/top-cwv-2023/#largest-contentful-paint-lcp&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Our first set of recommendations are for &lt;a href=&quot;https://web.dev/lcp/&quot;&gt;Largest Contentful Paint (LCP)&lt;/a&gt;, which is a measure of load performance. Of the three Core Web Vitals metrics, LCP is the one that the largest number of sites struggle with—only &lt;a href=&quot;https://datastudio.google.com/s/nw4gcbKA5o4&quot; rel=&quot;noopener&quot;&gt;about half&lt;/a&gt; of all sites on the web today meet the &lt;a href=&quot;https://web.dev/lcp/#what-is-a-good-lcp-score&quot;&gt;recommended threshold&lt;/a&gt;—so let&#39;s start there.&lt;/p&gt;
&lt;h3 id=&quot;ensure-the-lcp-resource-is-discoverable-from-the-html-source&quot;&gt;Ensure the LCP resource is discoverable from the HTML source &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/top-cwv-2023/#ensure-the-lcp-resource-is-discoverable-from-the-html-source&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;According to the &lt;a href=&quot;https://almanac.httparchive.org/en/2022/&quot; rel=&quot;noopener&quot;&gt;2022 Web Almanac&lt;/a&gt; by HTTP Archive, &lt;a href=&quot;https://almanac.httparchive.org/en/2022/performance#fig-8&quot; rel=&quot;noopener&quot;&gt;72%&lt;/a&gt; of mobile pages have an image as their LCP element, which means that for most sites to optimize their LCP, they&#39;ll need to ensure those images can load quickly.&lt;/p&gt;
&lt;p&gt;What may not be obvious to many developers is that the time it takes to load an image is just one part of the challenge. Another critical part is the time &lt;em&gt;before&lt;/em&gt; an image starts loading, and HTTP Archive data suggests that&#39;s actually where many sites get tripped up.&lt;/p&gt;
&lt;p&gt;In fact, of the pages where the LCP element was an image, &lt;a href=&quot;https://almanac.httparchive.org/en/2022/performance#lcp-static-discoverability&quot; rel=&quot;noopener&quot;&gt;39%&lt;/a&gt; of those images had source URLs that were not &lt;a href=&quot;https://web.dev/optimize-lcp/#optimize-when-the-resource-is-discovered&quot;&gt;discoverable&lt;/a&gt; from the HTML document source. In other words, those URLs were not found in standard HTML attributes (such as &lt;code&gt;&amp;lt;img src=&amp;quot;...&amp;quot;&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;link rel=&amp;quot;preload&amp;quot; href=&amp;quot;...&amp;quot;&amp;gt;&lt;/code&gt;), which would allow the browser to quickly discover them and start loading them right away.&lt;/p&gt;
&lt;p&gt;If a page needs to wait for CSS or JavaScript files to be fully downloaded, parsed, and processed before the image can even start loading, it may already be too late.&lt;/p&gt;
&lt;p&gt;As a general rule, if your LCP element is an image, the image&#39;s URL should always be discoverable from the HTML source. Some tips to make that possible are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Load the image using an &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; element with the &lt;code&gt;src&lt;/code&gt; or &lt;code&gt;srcset&lt;/code&gt; attribute.&lt;/strong&gt; Do not use non-standard attributes like &lt;code&gt;data-src&lt;/code&gt; that require JavaScript in order to render, as that will always be slower. &lt;a href=&quot;https://almanac.httparchive.org/en/2022/performance#lcp-lazy-loading&quot; rel=&quot;noopener&quot;&gt;9%&lt;/a&gt; of pages obscure their LCP image behind &lt;code&gt;data-src&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Prefer server-side rendering (SSR) over client-side rendering (CSR),&lt;/strong&gt; as SSR implies that the full page markup (including the image) is present in the HTML source. CSR solutions require JavaScript to run before the image can be discovered.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;If your image needs to be referenced from an external CSS or JS file, you can still include it in the HTML source via a &lt;code&gt;&amp;lt;link rel=&amp;quot;preload&amp;quot;&amp;gt;&lt;/code&gt; tag.&lt;/strong&gt; Note that images referenced by inline styles are not discoverable by the browser&#39;s &lt;a href=&quot;https://web.dev/preload-scanner/&quot;&gt;preload scanner&lt;/a&gt;, so even though they&#39;re found in the HTML source, discovery of them might still be blocked on the loading of other resources, so preloading can help in these cases.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To help you understand if your LCP image has discoverability problems, Lighthouse will be releasing a &lt;a href=&quot;https://github.com/GoogleChrome/lighthouse/issues/13738&quot; rel=&quot;noopener&quot;&gt;new audit&lt;/a&gt; in version 10.0 (expected January 2023).&lt;/p&gt;
&lt;p&gt;Ensuring the LCP resource is discoverable from the HTML source can lead to measurable improvements and it also unlocks additional opportunities to prioritize the resource, which is our next recommendation.&lt;/p&gt;
&lt;h3 id=&quot;ensure-the-lcp-resource-is-prioritized&quot;&gt;Ensure the LCP resource is prioritized &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/top-cwv-2023/#ensure-the-lcp-resource-is-prioritized&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Making sure the LCP resource can be discovered from the HTML source is a critical first step in ensuring the LCP resource can start loading early, but another important step is ensuring that the loading of that resource is &lt;a href=&quot;https://web.dev/optimize-lcp/#optimize-the-priority-the-resource-is-given&quot;&gt;prioritized&lt;/a&gt; and doesn&#39;t get queued behind a bunch of other, less important resources.&lt;/p&gt;
&lt;p&gt;For example, even if your LCP image is present in the HTML source using a standard &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag, if your page includes a dozen &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; of your document before that &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag, it may be a while before your image resource starts loading.&lt;/p&gt;
&lt;p&gt;The easiest way to solve this problem is to provide a hint to the browser about what resources are the highest priority by setting the new &lt;a href=&quot;https://web.dev/fetch-priority/&quot;&gt;&lt;code&gt;fetchpriority=&amp;quot;high&amp;quot;&lt;/code&gt;&lt;/a&gt; attribute on the &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; tag that loads your LCP image. This instructs the browser to load it earlier, rather than waiting for those scripts to complete.&lt;/p&gt;
&lt;p&gt;According to the Web Almanac, only &lt;a href=&quot;https://almanac.httparchive.org/en/2022/performance#lcp-prioritization&quot; rel=&quot;noopener&quot;&gt;0.03%&lt;/a&gt; of eligible pages are taking advantage of this new API, meaning there is plenty of opportunity for most sites on the web to improve LCP with very little work. While the &lt;code&gt;fetchpriority&lt;/code&gt; attribute is currently only supported in Chromium-based browsers, this API is a progressive enhancement that other browsers just ignore, so we strongly recommend developers use it now.&lt;/p&gt;
&lt;p&gt;For non-Chromium browsers, the only way to ensure the LCP resource is prioritized above other resources is to reference it earlier in the document. Using the example again of a site with lots of &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; of the document, if you wanted to ensure your LCP resource was prioritized ahead of those script resources, you could add a &lt;code&gt;&amp;lt;link rel=&amp;quot;preload&amp;quot;&amp;gt;&lt;/code&gt; tag before any of those scripts, or you could move those scripts to below the &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; later in the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt;. While this works, it&#39;s less ergonomic than using &lt;code&gt;fetchpriority&lt;/code&gt;, so we hope other browsers add support soon.&lt;/p&gt;
&lt;p&gt;Another critical aspect of prioritizing the LCP resource is to ensure you don&#39;t do anything that causes it to be &lt;strong&gt;deprioritized&lt;/strong&gt;, such as adding the &lt;code&gt;loading=&amp;quot;lazy&amp;quot;&lt;/code&gt; attribute. Today, &lt;a href=&quot;https://almanac.httparchive.org/en/2022/performance#lcp-lazy-loading&quot; rel=&quot;noopener&quot;&gt;10%&lt;/a&gt; of pages actually set &lt;code&gt;loading=&amp;quot;lazy&amp;quot;&lt;/code&gt; on their LCP image. Beware of image optimization solutions that indiscriminately apply lazy-loading behavior to all images. If they provide a way to override that behavior, be sure to use it for the LCP image. If you&#39;re not sure which image will be the LCP, try using heuristics to pick a reasonable candidate.&lt;/p&gt;
&lt;p&gt;Deferring non-critical resources is another way to effectively boost the relative priority of the LCP resource. For example, scripts that are not powering the user interface (like analytics scripts or social widgets) can be safely postponed until after the &lt;code&gt;load&lt;/code&gt; event fires, which ensures they won&#39;t compete with other critical resources (such as the LCP resource) for network bandwidth.&lt;/p&gt;
&lt;p&gt;To summarize, you should follow these best practices to ensure that the LCP resource is loaded early, and at high priority:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Add &lt;code&gt;fetchpriority=&amp;quot;high&amp;quot;&lt;/code&gt; to the &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag of your LCP image.&lt;/strong&gt; If the LCP resource is loaded via a&lt;code&gt; &amp;lt;link rel=&amp;quot;preload&amp;quot;&amp;gt;&lt;/code&gt; tag, fear not because you can also set &lt;code&gt;fetchpriority=&amp;quot;high&amp;quot;&lt;/code&gt; on that!&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Never set &lt;code&gt;loading=&amp;quot;lazy&amp;quot;&lt;/code&gt; on the &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag of your LCP image.&lt;/strong&gt; Doing this will deprioritize your image and delay when it starts loading.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Defer non-critical resources when possible.&lt;/strong&gt; Either by moving them to the end of your document, using native lazy-loading for &lt;a href=&quot;https://web.dev/browser-level-image-lazy-loading/&quot;&gt;images&lt;/a&gt; or &lt;a href=&quot;https://web.dev/iframe-lazy-loading/&quot;&gt;iframes&lt;/a&gt;, or loading them asynchronously via JavaScript.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;use-a-cdn-to-optimize-document-and-resource-ttfb&quot;&gt;Use a CDN to optimize document and resource TTFB &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/top-cwv-2023/#use-a-cdn-to-optimize-document-and-resource-ttfb&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The previous two recommendations focused on making sure your LCP resource is discovered early and prioritized so it can start loading right away. The final piece to this puzzle is making sure the initial document response arrives as quickly as possible too.&lt;/p&gt;
&lt;p&gt;The browser cannot start loading any subresources until it receives the first byte of the initial HTML document response, and the sooner that happens, the sooner everything else can start happening as well.&lt;/p&gt;
&lt;p&gt;This time is known as &lt;a href=&quot;https://web.dev/ttfb/&quot;&gt;Time to First Byte (TTFB)&lt;/a&gt;, and the best way to reduce TTFB is to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Serve your content as geographically close to your users as possible&lt;/li&gt;
&lt;li&gt;Cache that content so recently-requested content can be served again quickly.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The best way to do both of these things is to &lt;a href=&quot;https://web.dev/content-delivery-networks/&quot;&gt;use a CDN&lt;/a&gt;. CDNs distribute your resources to edge servers, which are spread across the globe, thus limiting the distance those resources have to travel over the wire to your users. CDNs also usually have fine-grained caching controls that can be customized and optimized for your site&#39;s needs.&lt;/p&gt;
&lt;p&gt;Many developers are familiar with using a CDN to host static assets, but CDNs can serve and cache HTML documents as well, even those that are dynamically generated.&lt;/p&gt;
&lt;p&gt;According to the Web Almanac, only &lt;a href=&quot;https://almanac.httparchive.org/en/2022/cdn#cdn-adoption&quot; rel=&quot;noopener&quot;&gt;29%&lt;/a&gt; of HTML document requests were served from a CDN, which means there is significant opportunity for sites to claim additional savings.&lt;/p&gt;
&lt;p&gt;Some tips for configuring your CDNs are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Consider increasing how long content is cached for (for example, is it actually critical that content is always fresh? Or can it be a few minutes stale?).&lt;/li&gt;
&lt;li&gt;Consider maybe even caching content indefinitely, and then purging the cache if/when you make an update.&lt;/li&gt;
&lt;li&gt;Explore whether you can move dynamic logic currently running on your origin server to the &lt;a href=&quot;https://en.wikipedia.org/wiki/Edge_computing&quot; rel=&quot;noopener&quot;&gt;edge&lt;/a&gt; (a feature of most modern CDNs).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In general, any time you can serve content directly from the edge (avoiding a trip to your origin server) it&#39;s a performance win. And even in cases where you &lt;em&gt;do&lt;/em&gt; have to make the journey all the way back to your origin server, CDNs are generally optimized to do that much more quickly, so it&#39;s a win either way.&lt;/p&gt;
&lt;h2 id=&quot;cumulative-layout-shift-cls&quot;&gt;Cumulative Layout Shift (CLS) &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/top-cwv-2023/#cumulative-layout-shift-cls&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The next set of recommendations are for &lt;a href=&quot;https://web.dev/cls/&quot;&gt;Cumulative Layout Shift (CLS)&lt;/a&gt;, which is a measure of visual stability on web pages. While CLS has &lt;a href=&quot;https://datastudio.google.com/s/gFjrTptD140&quot; rel=&quot;noopener&quot;&gt;improved a lot&lt;/a&gt; on the web since 2020, about a quarter of websites still do not meet the &lt;a href=&quot;https://web.dev/cls/#what-is-a-good-cls-score&quot;&gt;recommended threshold&lt;/a&gt;, so there remains a big opportunity for many sites to improve their user experience.&lt;/p&gt;
&lt;h3 id=&quot;set-explicit-sizes-on-any-content-loaded-from-the-page&quot;&gt;Set explicit sizes on any content loaded from the page &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/top-cwv-2023/#set-explicit-sizes-on-any-content-loaded-from-the-page&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://web.dev/cls/#layout-shifts-in-detail&quot;&gt;Layout shifts&lt;/a&gt; usually happen when existing content moves after other content finishes loading. Therefore, the primary way to mitigate this is to reserve any required space in advance as much as possible.&lt;/p&gt;
&lt;p&gt;The most straightforward way to fix layout shifts caused by unsized images is to &lt;strong&gt;explicitly set &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt; attributes&lt;/strong&gt; (or equivalent CSS properties). However, according to HTTP Archive, &lt;a href=&quot;https://almanac.httparchive.org/en/2022/performance#explicit-dimensions&quot; rel=&quot;noopener&quot;&gt;72%&lt;/a&gt; of pages have at least one unsized image. Without an explicit size, browsers will initially set a default height of &lt;code&gt;0px&lt;/code&gt; and may cause a noticeable layout shift when the image is finally loaded and the dimensions are discovered. This represents both a huge opportunity for the collective web—and that opportunity requires much less effort than some of the other recommendations suggested in this article.&lt;/p&gt;
&lt;p&gt;It&#39;s also important to keep in mind that images are not the only contributors to CLS. Layout shifts may be caused by other content that typically loads in after the page is initially rendered, including third-party ads or embedded videos. The &lt;a href=&quot;https://web.dev/aspect-ratio/&quot;&gt;&lt;code&gt;aspect-ratio&lt;/code&gt;&lt;/a&gt; property can help combat this. It&#39;s a relatively new CSS feature that allows developers to explicitly provide an aspect ratio to images as well as non-image elements. This will allow you to set a dynamic  &lt;code&gt;width&lt;/code&gt; (for example based on screen size), and have the browser automatically calculate the appropriate height, in much the same way as they do for images with dimensions.&lt;/p&gt;
&lt;p&gt;Sometimes it&#39;s not possible to know the exact size of dynamic content since it is, by its very nature, dynamic. However, even if you don&#39;t know the exact size, you can still take steps to reduce the severity of layout shifts. &lt;strong&gt;Setting a sensible &lt;code&gt;min-height&lt;/code&gt;&lt;/strong&gt; is almost always better than allowing the browser to use the default height of &lt;code&gt;0px&lt;/code&gt; for an empty element. Using a &lt;code&gt;min-height&lt;/code&gt; is also usually an easy fix as it still allows the container to grow to the final content height if needed—it has just reduced that amount of growth from the full amount to a hopefully more tolerable level.&lt;/p&gt;
&lt;h3 id=&quot;ensure-pages-are-eligible-for-bfcache&quot;&gt;Ensure pages are eligible for bfcache &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/top-cwv-2023/#ensure-pages-are-eligible-for-bfcache&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Browsers use a navigation mechanism called the &lt;a href=&quot;https://web.dev/bfcache/&quot;&gt;back/forward cache&lt;/a&gt;—or bfcache for short—to instantly load a page from earlier or later in the browser history directly from a memory snapshot.&lt;/p&gt;
&lt;p&gt;The bfcache is a significant browser-level performance optimization, and it entirely eliminates the layout shifts during page load, which for many sites is where most of their CLS occurs. The introduction of the bfcache caused &lt;a href=&quot;https://twitter.com/anniesullie/status/1491399685961293828?s=20&amp;amp;t=k7JgTjdO21uMpeOuOofroA&quot; rel=&quot;noopener&quot;&gt;the biggest improvement in CLS&lt;/a&gt; that we saw in 2022.&lt;/p&gt;
&lt;p&gt;Despite this, &lt;a href=&quot;https://almanac.httparchive.org/en/2022/performance#bfcache-eligibility&quot; rel=&quot;noopener&quot;&gt;a significant number of websites&lt;/a&gt; are ineligible for the bfcache and so are missing out on this free web performance win for a significant number of navigations. Unless your page is loading sensitive information that you don&#39;t want to be restored from memory, you&#39;ll want to make sure that your pages are eligible.&lt;/p&gt;
&lt;p&gt;Site owners should check that their pages are &lt;a href=&quot;https://web.dev/bfcache/#optimize-your-pages-for-bfcache&quot;&gt;eligible for the bfcache&lt;/a&gt; and work on any reasons why they are not. Chrome already &lt;a href=&quot;https://web.dev/bfcache/#test-to-ensure-your-pages-are-cacheable&quot;&gt;has a bfcache tester in DevTools&lt;/a&gt; and this year we plan to enhance tooling here with &lt;a href=&quot;https://github.com/GoogleChrome/lighthouse/issues/13960&quot; rel=&quot;noopener&quot;&gt;a new Lighthouse audit performing a similar test&lt;/a&gt; and &lt;a href=&quot;https://chromestatus.com/feature/5684908759449600&quot; rel=&quot;noopener&quot;&gt;an API to measure this in the field&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;While we have included the bfcache in the CLS section, as we saw the biggest gains there so far, the bfcache will generally also improve other Core Web Vitals too. It is one of &lt;a href=&quot;https://calendar.perfplanet.com/2022/fast-is-good-instant-is-better/&quot; rel=&quot;noopener&quot;&gt;a number of instant navigations&lt;/a&gt; available to drastically improve page navigations.&lt;/p&gt;
&lt;h3 id=&quot;avoid-animationstransitions-that-use-layout-inducing-css-properties&quot;&gt;Avoid animations/transitions that use layout-inducing CSS properties &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/top-cwv-2023/#avoid-animationstransitions-that-use-layout-inducing-css-properties&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Another common source of layout shifts is when elements are animated. For example, cookie banners or other notification banners that slide in from the top or bottom are often a contributor to CLS. This is particularly problematic when these banners push other content out of the way, but even when they don&#39;t, animating them can still impact CLS.&lt;/p&gt;
&lt;p&gt;While HTTP Archive data can&#39;t conclusively connect animations to layout shifts, the data does show that pages that animate any CSS property that &lt;em&gt;could&lt;/em&gt; affect layout are 15% less likely to have &amp;quot;good&amp;quot; CLS than pages overall. Some properties are associated with worse CLS than others. For instance, pages that animate &lt;code&gt;margin&lt;/code&gt; or &lt;code&gt;border&lt;/code&gt; widths have &amp;quot;poor&amp;quot; CLS at almost twice the rate that pages overall are assessed as poor.&lt;/p&gt;
&lt;p&gt;This is perhaps not surprising, because any time you transition or animate &lt;em&gt;any&lt;/em&gt; layout-inducing CSS property, it will result in &lt;a href=&quot;https://web.dev/cls/#layout-shifts-in-detail&quot;&gt;layout shifts&lt;/a&gt;, and if those layout shifts are not within 500 milliseconds of a user interaction, they will impact CLS.&lt;/p&gt;
&lt;p&gt;What may be surprising to some developers is that this is true even in cases where the element is taken outside of the normal document flow. For example, absolutely positioned elements that animate &lt;code&gt;top&lt;/code&gt; or &lt;code&gt;left&lt;/code&gt; will cause layout shifts, even if they aren&#39;t pushing other content around. However, if instead of animating &lt;code&gt;top&lt;/code&gt; or &lt;code&gt;left&lt;/code&gt; you animate &lt;code&gt;transform:translateX()&lt;/code&gt; or &lt;code&gt;transform:translateY()&lt;/code&gt;, it won&#39;t cause the browser to update page layout and thus won&#39;t produce any layout shifts.&lt;/p&gt;
&lt;p&gt;Preferring animation of CSS properties that can be updated on the browser&#39;s compositor thread has long been &lt;a href=&quot;https://web.dev/animations-guide/&quot;&gt;a performance best practice&lt;/a&gt; because it moves that work onto the GPU and off the main thread. And in addition to it being a general performance best practice, it can also help improve CLS.&lt;/p&gt;
&lt;p&gt;As a general rule, never animate or transition any CSS property that requires the browser to update the page layout, unless you&#39;re doing it in response to a user tap or key press (though &lt;a href=&quot;https://web.dev/cls/#user-initiated-layout-shifts&quot;&gt;not &lt;code&gt;hover&lt;/code&gt;&lt;/a&gt;). And whenever possible, prefer transitions and animations using the CSS &lt;a href=&quot;https://developer.mozilla.org/docs/Web/CSS/transform&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;transform&lt;/code&gt;&lt;/a&gt; property.&lt;/p&gt;
&lt;p&gt;The Lighthouse audit &lt;a href=&quot;https://developer.chrome.com/docs/lighthouse/performance/non-composited-animations/&quot; rel=&quot;noopener&quot;&gt;Avoid non-composited animations&lt;/a&gt; will warn when a page animates potentially slow CSS properties.&lt;/p&gt;
&lt;h2 id=&quot;first-input-delay-fid&quot;&gt;First Input Delay (FID) &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/top-cwv-2023/#first-input-delay-fid&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Our last set of recommendations are for &lt;a href=&quot;https://web.dev/fid/&quot;&gt;First Input Delay (FID)&lt;/a&gt;, which is a measure of a page&#39;s responsiveness to user interactions. While most sites on the web currently &lt;a href=&quot;https://datastudio.google.com/s/vax9YUKhRN0&quot; rel=&quot;noopener&quot;&gt;score very well&lt;/a&gt; on FID, we&#39;ve &lt;a href=&quot;https://web.dev/better-responsiveness-metric/#what-improvements-are-we-considering&quot;&gt;documented&lt;/a&gt; shortcomings of the FID metric in the past, and we believe there is still a lot of opportunity for sites to improve their overall responsiveness to user interactions.&lt;/p&gt;
&lt;p&gt;Our new &lt;a href=&quot;https://web.dev/inp/&quot;&gt;Interaction to Next Paint (INP)&lt;/a&gt; metric is a possible successor to FID, and all of the recommendations below apply equally well to both FID and INP. Given that sites &lt;a href=&quot;https://almanac.httparchive.org/en/2022/performance#inp-as-a-hypothetical-cwv-metric&quot; rel=&quot;noopener&quot;&gt;perform worse&lt;/a&gt; on INP than FID, especially on mobile, we encourage developers to seriously consider these responsiveness recommendations, despite having &amp;quot;good&amp;quot; FID.&lt;/p&gt;
&lt;h3 id=&quot;avoid-or-break-up-long-tasks&quot;&gt;Avoid or break up long tasks &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/top-cwv-2023/#avoid-or-break-up-long-tasks&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Tasks are any piece of discrete work that the browser does. Tasks include rendering, layout, parsing, and compiling and executing scripts. When tasks become &lt;a href=&quot;https://web.dev/long-tasks-devtools/#what-are-long-tasks&quot;&gt;long tasks&lt;/a&gt;—that is, 50 milliseconds or longer—they block the main thread from being able to respond quickly to user inputs.&lt;/p&gt;
&lt;p&gt;Per the Web Almanac, there&#39;s &lt;a href=&quot;https://almanac.httparchive.org/en/2022/javascript#long-tasksblocking-time&quot; rel=&quot;noopener&quot;&gt;plenty of evidence&lt;/a&gt; to suggest that developers could be doing more to avoid or break up long tasks. While breaking up long tasks may not be as low of an effort as other recommendations in this article, it&#39;s less effort than other techniques not offered in this article.&lt;/p&gt;
&lt;p&gt;While you should always strive to do as little work as possible in JavaScript, you can help the main thread quite a bit by &lt;a href=&quot;https://web.dev/optimize-long-tasks/&quot;&gt;breaking up long tasks into smaller ones&lt;/a&gt;. You can accomplish this by &lt;a href=&quot;https://web.dev/optimize-long-tasks/#use-asyncawait-to-create-yield-points&quot;&gt;yielding to the main thread&lt;/a&gt; often so that rendering updates and other user interactions can occur more quickly.&lt;/p&gt;
&lt;p&gt;Another option is to consider using APIs such as &lt;a href=&quot;https://web.dev/optimize-long-tasks/#yield-only-when-necessary&quot;&gt;&lt;code&gt;isInputPending&lt;/code&gt;&lt;/a&gt; and the &lt;a href=&quot;https://web.dev/optimize-long-tasks/#a-dedicated-scheduler-api&quot;&gt;Scheduler API&lt;/a&gt;. &lt;code&gt;isInputPending&lt;/code&gt; is a function that returns a boolean value that indicates whether a user input is pending. If it returns &lt;code&gt;true&lt;/code&gt;, you can yield to the main thread so it can handle the pending user input.&lt;/p&gt;
&lt;p&gt;The Scheduler API is a more advanced approach, which allows you to schedule work based on a system of priorities that take into account whether the work being done is user-visible or backgrounded.&lt;/p&gt;
&lt;p&gt;By breaking up long tasks, you&#39;re giving the browser more opportunities to fit in critical user-visible work, such as dealing with interactions and any resulting rendering updates.&lt;/p&gt;
&lt;h3 id=&quot;avoid-unnecessary-javascript&quot;&gt;Avoid unnecessary JavaScript &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/top-cwv-2023/#avoid-unnecessary-javascript&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;There&#39;s no doubt about it: &lt;a href=&quot;https://almanac.httparchive.org/en/2022/javascript#how-much-javascript-do-we-load&quot; rel=&quot;noopener&quot;&gt;websites are shipping more JavaScript than ever before&lt;/a&gt;, and the trend doesn&#39;t look like it&#39;s changing any time soon. When you ship too much JavaScript, you&#39;re creating an environment where tasks are competing for the main thread&#39;s attention. This can definitely affect your website&#39;s responsiveness, especially during that crucial startup period.&lt;/p&gt;
&lt;p&gt;This is not an unsolvable problem, however. You do have some options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use the &lt;a href=&quot;https://developer.chrome.com/docs/devtools/coverage/&quot; rel=&quot;noopener&quot;&gt;coverage tool&lt;/a&gt; in Chrome DevTools to find unused code in your website&#39;s resources. By reducing the size of the resources you need during startup, you can ensure your website spends less time parsing and compiling code, which leads to a smoother initial user experience.&lt;/li&gt;
&lt;li&gt;Sometimes the unused code you find using the coverage tool is marked &amp;quot;unused&amp;quot; because it wasn&#39;t executed during startup, but is still necessary for some functionality in the future. This is code that you can move to a separate bundle via &lt;a href=&quot;https://web.dev/reduce-javascript-payloads-with-code-splitting/&quot;&gt;code splitting&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;If you&#39;re using a tag manager, be sure to &lt;a href=&quot;https://web.dev/tag-best-practices/&quot;&gt;periodically check your tags to make sure they are optimized&lt;/a&gt;, or even if they&#39;re still being used. Older tags with unused code can be cleared out to make your tag manager&#39;s JavaScript smaller and more efficient.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;avoid-large-rendering-updates&quot;&gt;Avoid large rendering updates &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/top-cwv-2023/#avoid-large-rendering-updates&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;JavaScript isn&#39;t the only thing that can affect your website&#39;s responsiveness. Rendering can be a type of expensive work in its own right—and when large rendering updates happen, they can interfere with your website&#39;s ability to respond to user inputs.&lt;/p&gt;
&lt;p&gt;Optimizing rendering work isn&#39;t a straightforward process, and it often depends on what you&#39;re trying to achieve. Even so, there are some things you can do to ensure that your rendering updates are reasonable, and don&#39;t sprawl into long tasks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Avoid 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; for doing any non-visual work. &lt;code&gt;requestAnimationFrame()&lt;/code&gt; calls are handled during the rendering phase of the event loop, and when too much work is done during this step, rendering updates can be delayed. It&#39;s essential that any work you&#39;re doing with &lt;code&gt;requestAnimationFrame()&lt;/code&gt; is reserved strictly for tasks that involve rendering updates.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.chrome.com/docs/lighthouse/performance/dom-size/&quot; rel=&quot;noopener&quot;&gt;Keep your DOM size small&lt;/a&gt;. DOM size and the intensity of layout work are correlated. When the renderer has to update the layout for a very large DOM, the work required to recalculate its layout can increase significantly.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/docs/Web/CSS/CSS_Containment&quot; rel=&quot;noopener&quot;&gt;Use CSS containment&lt;/a&gt;. CSS containment relies on the CSS &lt;code&gt;contain&lt;/code&gt; property, which gives instructions to the browser about how to do layout work for the container the &lt;code&gt;contain&lt;/code&gt; property is set on, including even isolating the scope of layout and rendering to a specific root in the DOM. It&#39;s not always an easy process, but by isolating areas containing complex layouts, you can avoid doing layout and rendering work for them that isn&#39;t necessary.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/top-cwv-2023/#conclusion&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Improving page performance can seem like a daunting task, especially given that there is a mountain of guidance across the web to consider. By focusing on these recommendations, however, you can approach the problem with focus and purpose, and hopefully move the needle for your website&#39;s Core Web Vitals.&lt;/p&gt;
&lt;p&gt;While the recommendations listed here are by no means exhaustive, we do believe—based on careful analysis of the state of the web—that these recommendations are the most effective ways that sites can improve their Core Web Vitals performance in 2023.&lt;/p&gt;
&lt;p&gt;If you&#39;d like to go beyond the recommendations listed here, check out these optimization guides for more information:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://web.dev/optimize-lcp/&quot;&gt;Optimize LCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://web.dev/optimize-cls/&quot;&gt;Optimize CLS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://web.dev/optimize-fid/&quot;&gt;Optimize FID&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://web.dev/optimize-inp/&quot;&gt;Optimize INP&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here&#39;s to a new year, and a faster web for all! May your sites be fast for your users in all the ways that matter most.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Photo by &lt;a href=&quot;https://unsplash.com/@devintavery&quot; rel=&quot;noopener&quot;&gt;Devin Avery&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
</content>
    <author>
      <name>Philip Walton</name>
    </author><author>
      <name>Rick Viscomi</name>
    </author><author>
      <name>Barry Pollard</name>
    </author><author>
      <name>Brendan Kenny</name>
    </author><author>
      <name>Jeremy Wagner</name>
    </author>
  </entry>
  
  <entry>
    <title>Lighthouse user flows</title>
    <link href="https://web.dev/lighthouse-user-flows/"/>
    <updated>2021-11-03T00:00:00Z</updated>
    <id>https://web.dev/lighthouse-user-flows/</id>
    <content type="html" mode="escaped">&lt;p&gt;Lighthouse is a fantastic tool for testing performance and best practices during initial page load. However, it&#39;s traditionally been difficult to use Lighthouse to analyze other aspects of the life of a page, such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Page loads with a warm cache&lt;/li&gt;
&lt;li&gt;Pages with an activated Service Worker&lt;/li&gt;
&lt;li&gt;Accounting for potential user interactions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This means that Lighthouse can miss vital information. The &lt;a href=&quot;https://web.dev/vitals/#core-web-vitals&quot;&gt;Core Web Vitals&lt;/a&gt; are based on &lt;em&gt;all&lt;/em&gt; page loads, not just those with an empty cache. Additionally, metrics like &lt;a href=&quot;https://web.dev/cls/&quot;&gt;Cumulative Layout Shift (CLS)&lt;/a&gt; are measurable for the entire time a page is open.&lt;/p&gt;
&lt;p&gt;Lighthouse has a new user flow API that allows lab testing at any point within a page&#39;s lifespan. &lt;a href=&quot;https://github.com/puppeteer/puppeteer&quot; rel=&quot;noopener&quot;&gt;Puppeteer&lt;/a&gt; is used to script page loads and trigger synthetic user interactions, and Lighthouse can be invoked in multiple ways to capture key insights during those interactions. This means that performance can be measured during page load &lt;em&gt;and&lt;/em&gt; during interactions with the page. Accessibility checks can be run in CI, not just on the initial view but deep within your checkout flow to make sure nothing regresses.&lt;/p&gt;
&lt;p&gt;Almost any Puppeteer script written to ensure a working user flow can now have Lighthouse inserted at any point to measure performance and best practices throughout. This tutorial will walk through the new Lighthouse modes that can measure different parts of user flows: navigations, snapshots, and timespans.&lt;/p&gt;
&lt;h2 id=&quot;setup&quot;&gt;Setup &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/lighthouse-user-flows/#setup&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The user flow APIs are still in preview, but they are available in Lighthouse today. To try out the demos below, you&#39;ll need Node version 14 or later. Create an empty directory and in it run:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Default to ES modules.&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;{&quot;type&quot;: &quot;module&quot;}&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; package.json&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;# Init npm project without the wizard.&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; init -y&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token comment&quot;&gt;# Dependencies for these examples.&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; lighthouse puppeteer &lt;span class=&quot;token function&quot;&gt;open&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&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;Gotchas&lt;/strong&gt;&lt;/p&gt;&lt;div class=&quot; flow&quot;&gt; Without the &lt;code&gt;{&amp;quot;type&amp;quot;: &amp;quot;module&amp;quot;}&lt;/code&gt; line, &lt;code&gt;npm init -y&lt;/code&gt; will default to CommonJS instead of modules. The following code can still be used, but you will have to switch to &lt;code&gt;require()&lt;/code&gt; instead of &lt;code&gt;import&lt;/code&gt; to bring in dependencies. &lt;/div&gt;&lt;/aside&gt;
&lt;h2 id=&quot;navigations&quot;&gt;Navigations &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/lighthouse-user-flows/#navigations&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The new Lighthouse &amp;quot;navigation&amp;quot; mode is actually giving a name to the (up until now) standard Lighthouse behavior: analyze the cold load of a page. This is the mode to use to monitor page load performance, but user flows also open up the possibility of new insights.&lt;/p&gt;
&lt;p&gt;To script Lighthouse capturing a page load:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Use puppeteer to open the browser.&lt;/li&gt;
&lt;li&gt;Start a Lighthouse user flow.&lt;/li&gt;
&lt;li&gt;Navigate to the target URL.&lt;/li&gt;
&lt;/ol&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;import&lt;/span&gt; fs &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;fs&#39;&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;import&lt;/span&gt; open &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;open&#39;&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;import&lt;/span&gt; puppeteer &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;puppeteer&#39;&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;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;startFlow&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;lighthouse/lighthouse-core/fraggle-rock/api.js&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;captureReport&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;const&lt;/span&gt; browser &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; puppeteer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;launch&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 literal-property property&quot;&gt;headless&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&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;const&lt;/span&gt; page &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; browser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;newPage&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;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; flow &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;startFlow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;page&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 literal-property property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Single Navigation&#39;&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;await&lt;/span&gt; flow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;navigate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;https://web.dev/performance-scoring/&#39;&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;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; browser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;close&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;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; report &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; flow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;generateReport&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;  fs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;writeFileSync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;flow.report.html&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; report&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;open&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;flow.report.html&#39;&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 literal-property property&quot;&gt;wait&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&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 punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token function&quot;&gt;captureReport&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;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;This is the simplest flow. When opened, the report shows a summary view with only the single step. Clicking on that step will reveal a traditional Lighthouse report for that navigation.&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt=&quot;A Lighthouse flow report showing a single navigation&quot; decoding=&quot;async&quot; height=&quot;333&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/kb0RiS8uXSLoDq8nDlxa.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/kb0RiS8uXSLoDq8nDlxa.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/kb0RiS8uXSLoDq8nDlxa.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/kb0RiS8uXSLoDq8nDlxa.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/kb0RiS8uXSLoDq8nDlxa.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/kb0RiS8uXSLoDq8nDlxa.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/kb0RiS8uXSLoDq8nDlxa.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/kb0RiS8uXSLoDq8nDlxa.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/kb0RiS8uXSLoDq8nDlxa.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/kb0RiS8uXSLoDq8nDlxa.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/kb0RiS8uXSLoDq8nDlxa.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/kb0RiS8uXSLoDq8nDlxa.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/kb0RiS8uXSLoDq8nDlxa.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/kb0RiS8uXSLoDq8nDlxa.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/kb0RiS8uXSLoDq8nDlxa.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/kb0RiS8uXSLoDq8nDlxa.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/kb0RiS8uXSLoDq8nDlxa.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/kb0RiS8uXSLoDq8nDlxa.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
  &lt;figcaption&gt;&lt;a href=&quot;https://chalk-confused-roundworm.glitch.me/&quot;&gt;See the report live&lt;/a&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;As is typical with Lighthouse, this page is loaded with any cache or local storage cleared first, but real users visiting a site will have a mixture of visits with cold and warm caches, and there can be a large performance difference between a cold load like this and a user returning to the page with a still-warm cache.&lt;/p&gt;
&lt;h3 id=&quot;capturing-a-warm-load&quot;&gt;Capturing a warm load &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/lighthouse-user-flows/#capturing-a-warm-load&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;You can also add a second navigation to this script, this time disabling the clearing of cache and storage that Lighthouse does by default in navigations. This next example loads an article on web.dev itself to see how much it benefits from caching:&lt;/p&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;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;captureReport&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;const&lt;/span&gt; browser &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; puppeteer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;launch&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 literal-property property&quot;&gt;headless&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&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;const&lt;/span&gt; page &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; browser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;newPage&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;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; testUrl &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;https://web.dev/performance-scoring/&#39;&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;const&lt;/span&gt; flow &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;startFlow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;page&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 literal-property property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Cold and warm navigations&#39;&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;await&lt;/span&gt; flow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;navigate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;testUrl&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 literal-property property&quot;&gt;stepName&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Cold navigation&#39;&lt;/span&gt;&lt;br /&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;await&lt;/span&gt; flow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;navigate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;testUrl&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 literal-property property&quot;&gt;stepName&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Warm navigation&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;configContext&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;settingsOverrides&lt;/span&gt;&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 literal-property property&quot;&gt;disableStorageReset&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&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 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;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;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; browser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;close&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;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; report &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; flow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;generateReport&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;  fs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;writeFileSync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;flow.report.html&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; report&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;open&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;flow.report.html&#39;&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 literal-property property&quot;&gt;wait&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&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 punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token function&quot;&gt;captureReport&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;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;The resulting flow report looks something like this:&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt=&quot;A Lighthouse flow report showing two navigations, one cold and one warm, which has a higher performance score&quot; decoding=&quot;async&quot; height=&quot;400&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4i28YDRuSaCxxJxtzigX.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4i28YDRuSaCxxJxtzigX.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4i28YDRuSaCxxJxtzigX.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4i28YDRuSaCxxJxtzigX.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4i28YDRuSaCxxJxtzigX.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4i28YDRuSaCxxJxtzigX.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4i28YDRuSaCxxJxtzigX.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4i28YDRuSaCxxJxtzigX.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4i28YDRuSaCxxJxtzigX.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4i28YDRuSaCxxJxtzigX.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4i28YDRuSaCxxJxtzigX.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4i28YDRuSaCxxJxtzigX.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4i28YDRuSaCxxJxtzigX.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4i28YDRuSaCxxJxtzigX.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4i28YDRuSaCxxJxtzigX.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4i28YDRuSaCxxJxtzigX.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4i28YDRuSaCxxJxtzigX.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4i28YDRuSaCxxJxtzigX.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
  &lt;figcaption&gt;&lt;a href=&quot;https://energetic-pattern-polish.glitch.me/&quot;&gt;See the report live&lt;/a&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The combination of cold and warm loads offers a fuller picture of what real users are experiencing. If you have a site where users load many pages in the same visit, this may be able to give you a more realistic look at what they&#39;re experiencing in the field.&lt;/p&gt;
&lt;h2 id=&quot;snapshots&quot;&gt;Snapshots &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/lighthouse-user-flows/#snapshots&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Snapshots are a new mode that runs Lighthouse audits at a single point in time. Unlike a normal Lighthouse run, the page is not reloaded. This unlocks the ability to set up a page and test it in its exact state: with a drop-down open or a form partially filled in, for example.&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; Not all Lighthouse audits can be run in this mode. Many of the performance metrics are currently defined as beginning with a page load and so are not applicable in a snapshot, but the accessibility audits and many of the performance best practices can still yield important checks. &lt;/div&gt;&lt;/aside&gt;
&lt;p&gt;For this example, suppose you want to check that some new UI for Advanced Settings within &lt;a href=&quot;https://squoosh.app/&quot; rel=&quot;noopener&quot;&gt;Squoosh&lt;/a&gt; passes the automated Lighthouse checks. These settings are only visible if an image has been loaded and the options menu is expanded to show the advanced settings.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt=&quot;The Squoosh advanced settings menu&quot; decoding=&quot;async&quot; height=&quot;515&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 399px) 399px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/2AJz5ievB1sBVcnivsqT.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/2AJz5ievB1sBVcnivsqT.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/2AJz5ievB1sBVcnivsqT.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/2AJz5ievB1sBVcnivsqT.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/2AJz5ievB1sBVcnivsqT.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/2AJz5ievB1sBVcnivsqT.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/2AJz5ievB1sBVcnivsqT.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/2AJz5ievB1sBVcnivsqT.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/2AJz5ievB1sBVcnivsqT.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/2AJz5ievB1sBVcnivsqT.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/2AJz5ievB1sBVcnivsqT.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/2AJz5ievB1sBVcnivsqT.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/2AJz5ievB1sBVcnivsqT.png?auto=format&amp;w=798 798w&quot; width=&quot;399&quot; /&gt;
  &lt;figcaption&gt;The Squoosh advanced settings menu&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;This process is scriptable with Puppeteer and you can actually take a Lighthouse snapshot at each step:&lt;/p&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;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;captureReport&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;const&lt;/span&gt; browser &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; puppeteer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;launch&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 literal-property property&quot;&gt;headless&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&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;const&lt;/span&gt; page &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; browser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;newPage&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;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; flow &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;startFlow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;page&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 literal-property property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Squoosh snapshots&#39;&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;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;goto&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;https://squoosh.app/&#39;&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 literal-property property&quot;&gt;waitUntil&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;networkidle0&#39;&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;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;// Wait for first demo-image button, then open it.&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; demoImageSelector &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;ul[class*=&quot;demos&quot;] button&#39;&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;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;waitForSelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;demoImageSelector&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;await&lt;/span&gt; flow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;snapshot&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 literal-property property&quot;&gt;stepName&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Page loaded&#39;&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;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;click&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;demoImageSelector&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;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;// Wait for advanced settings button in UI, then open them.&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; advancedSettingsSelector &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;form label[class*=&quot;option-reveal&quot;]&#39;&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;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;waitForSelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;advancedSettingsSelector&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;await&lt;/span&gt; flow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;snapshot&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 literal-property property&quot;&gt;stepName&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Demo loaded&#39;&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;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;click&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;advancedSettingsSelector&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;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; flow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;snapshot&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 literal-property property&quot;&gt;stepName&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Advanced settings opened&#39;&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;br /&gt;  browser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;close&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;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; report &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; flow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;generateReport&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;  fs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;writeFileSync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;flow.report.html&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; report&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;open&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;flow.report.html&#39;&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 literal-property property&quot;&gt;wait&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&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 punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token function&quot;&gt;captureReport&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;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;The resulting report shows that results are generally good, but there may be some accessibility criteria that need to be checked out manually:&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt=&quot;A Lighthouse flow report showing a set of snapshots taken&quot; decoding=&quot;async&quot; height=&quot;433&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4OnCFHNkZtIpNsLSw0e3.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4OnCFHNkZtIpNsLSw0e3.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4OnCFHNkZtIpNsLSw0e3.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4OnCFHNkZtIpNsLSw0e3.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4OnCFHNkZtIpNsLSw0e3.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4OnCFHNkZtIpNsLSw0e3.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4OnCFHNkZtIpNsLSw0e3.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4OnCFHNkZtIpNsLSw0e3.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4OnCFHNkZtIpNsLSw0e3.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4OnCFHNkZtIpNsLSw0e3.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4OnCFHNkZtIpNsLSw0e3.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4OnCFHNkZtIpNsLSw0e3.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4OnCFHNkZtIpNsLSw0e3.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4OnCFHNkZtIpNsLSw0e3.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4OnCFHNkZtIpNsLSw0e3.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4OnCFHNkZtIpNsLSw0e3.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4OnCFHNkZtIpNsLSw0e3.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/4OnCFHNkZtIpNsLSw0e3.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
  &lt;figcaption&gt;&lt;a href=&quot;https://ivy-cloudy-blackcurrant.glitch.me/&quot;&gt;See the report live&lt;/a&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;timespans&quot;&gt;Timespans &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/lighthouse-user-flows/#timespans&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;One of the biggest differences between performance results &lt;a href=&quot;https://web.dev/user-centric-performance-metrics/#in-the-field&quot;&gt;in the field&lt;/a&gt; (like from CrUX) and &lt;a href=&quot;https://web.dev/user-centric-performance-metrics/#in-the-lab&quot;&gt;in the lab&lt;/a&gt; (like from Lighthouse) is the lack of user input. This is where a timespan—the last user flow mode—can help.&lt;/p&gt;
&lt;p&gt;A timespan runs Lighthouse audits over some period of time, which may or may not include a navigation. This is a great way to capture what&#39;s going on with a page during interactions.  For instance, by default Lighthouse measures CLS during page load, but in the field, CLS is measured from initial navigation until the page is closed. If user interactions are the trigger of CLS, this is something Lighthouse previously wouldn&#39;t be able to catch and help fix.&lt;/p&gt;
&lt;p&gt;To demonstrate this, here is a &lt;a href=&quot;https://pie-charmed-treatment.glitch.me/&quot; rel=&quot;noopener&quot;&gt;test site&lt;/a&gt; that simulates ads being injected into an article during scroll without space having been reserved for them. In a long series of cards, an occasional red square is added when its slot enters the viewport. Since space was not reserved for these red squares, the cards below them are shifted out of the way, causing layout shifts.&lt;/p&gt;
&lt;p&gt;A regular Lighthouse navigation will have a CLS of 0. However, once scrolled, the page will have problematic layout shifts and the CLS value will rise.&lt;/p&gt;
&lt;figure&gt;
  &lt;video controls=&quot;&quot; height=&quot;640&quot; muted=&quot;&quot; width=&quot;360&quot; style=&quot;--vid-width: 360; --vid-height: 640&quot;&gt;      &lt;source src=&quot;https://storage.googleapis.com/web-dev-uploads/video/MtjnObpuceYe3ijODN3a79WrxLU2/Qi6B5SNt6Xk7rZ3055DO.mov&quot; type=&quot;video/mp4&quot; /&gt;    &lt;/video&gt;
  &lt;figcaption&gt;&lt;a href=&quot;https://pie-charmed-treatment.glitch.me/&quot;&gt;Try the demo site&lt;/a&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The following script will produce a user flow report with both actions, to show the difference.&lt;/p&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;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;captureReport&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;const&lt;/span&gt; browser &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; puppeteer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;launch&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 literal-property property&quot;&gt;headless&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&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;const&lt;/span&gt; page &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; browser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;newPage&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 comment&quot;&gt;// Get a session handle to be able to send protocol commands to the page.&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; session &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;target&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;span class=&quot;token function&quot;&gt;createCDPSession&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;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; testUrl &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;https://pie-charmed-treatment.glitch.me/&#39;&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;const&lt;/span&gt; flow &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;startFlow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;page&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 literal-property property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;CLS during navigation and on scroll&#39;&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;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;// Regular Lighthouse navigation.&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; flow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;navigate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;testUrl&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 literal-property property&quot;&gt;stepName&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Navigate only&#39;&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;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;// Navigate and scroll timespan.&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; flow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;startTimespan&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 literal-property property&quot;&gt;stepName&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Navigate and scroll&#39;&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;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;goto&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;testUrl&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 literal-property property&quot;&gt;waitUntil&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;networkidle0&#39;&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 comment&quot;&gt;// We need the ability to scroll like a user. There&#39;s not a direct puppeteer function for this, but we can use the DevTools Protocol and issue a Input.synthesizeScrollGesture event, which has convenient parameters like repetitions and delay to somewhat simulate a more natural scrolling gesture.&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token comment&quot;&gt;// https://chromedevtools.github.io/devtools-protocol/tot/Input/#method-synthesizeScrollGesture&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; session&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;Input.synthesizeScrollGesture&#39;&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 literal-property property&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;yDistance&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2500&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;speed&lt;/span&gt;&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;br /&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;repeatCount&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token literal-property property&quot;&gt;repeatDelayMs&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;250&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;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;await&lt;/span&gt; flow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;endTimespan&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;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; browser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;close&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;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; report &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; flow&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;generateReport&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;  fs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;writeFileSync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;flow.report.html&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; report&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;open&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;flow.report.html&#39;&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 literal-property property&quot;&gt;wait&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&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 punctuation&quot;&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;token function&quot;&gt;captureReport&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;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;This generates a report comparing a regular navigation to a timespan which contains both a navigation and scrolling afterwards:&lt;/p&gt;
&lt;figure&gt;
  &lt;img alt=&quot;A Lighthouse flow report showing a set of snapshots taken&quot; decoding=&quot;async&quot; height=&quot;367&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 800px) 800px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/wAkMF4T9IxpS82vODMdY.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/wAkMF4T9IxpS82vODMdY.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/wAkMF4T9IxpS82vODMdY.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/wAkMF4T9IxpS82vODMdY.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/wAkMF4T9IxpS82vODMdY.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/wAkMF4T9IxpS82vODMdY.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/wAkMF4T9IxpS82vODMdY.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/wAkMF4T9IxpS82vODMdY.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/wAkMF4T9IxpS82vODMdY.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/wAkMF4T9IxpS82vODMdY.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/wAkMF4T9IxpS82vODMdY.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/wAkMF4T9IxpS82vODMdY.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/wAkMF4T9IxpS82vODMdY.png?auto=format&amp;w=845 845w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/wAkMF4T9IxpS82vODMdY.png?auto=format&amp;w=964 964w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/wAkMF4T9IxpS82vODMdY.png?auto=format&amp;w=1098 1098w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/wAkMF4T9IxpS82vODMdY.png?auto=format&amp;w=1252 1252w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/wAkMF4T9IxpS82vODMdY.png?auto=format&amp;w=1428 1428w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/wAkMF4T9IxpS82vODMdY.png?auto=format&amp;w=1600 1600w&quot; width=&quot;800&quot; /&gt;
  &lt;figcaption&gt;&lt;a href=&quot;https://abaft-burnt-title.glitch.me/&quot;&gt;See the report live&lt;/a&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Digging into each step, the navigation-only step shows a CLS of 0. Great site!&lt;/p&gt;
&lt;figure&gt;
&lt;img alt=&quot;The Lighthouse report covering only page navigation with all green metrics&quot; decoding=&quot;async&quot; height=&quot;364&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 400px) 400px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/ZAKscmqryi5KVWOMiB5y.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/ZAKscmqryi5KVWOMiB5y.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/ZAKscmqryi5KVWOMiB5y.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/ZAKscmqryi5KVWOMiB5y.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/ZAKscmqryi5KVWOMiB5y.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/ZAKscmqryi5KVWOMiB5y.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/ZAKscmqryi5KVWOMiB5y.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/ZAKscmqryi5KVWOMiB5y.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/ZAKscmqryi5KVWOMiB5y.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/ZAKscmqryi5KVWOMiB5y.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/ZAKscmqryi5KVWOMiB5y.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/ZAKscmqryi5KVWOMiB5y.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/ZAKscmqryi5KVWOMiB5y.png?auto=format&amp;w=800 800w&quot; width=&quot;400&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;However the &amp;quot;Navigate and scroll&amp;quot; step tells a different story. Currently only Total Blocking Time and Cumulative Layout Shift are available in timespans, but the lazy-loaded content on this page clearly tanks the CLS for the site.&lt;/p&gt;
&lt;figure&gt;
&lt;img alt=&quot;The Lighthouse report covering page navigation and scrolling with a failing CLS&quot; decoding=&quot;async&quot; height=&quot;305&quot; loading=&quot;lazy&quot; sizes=&quot;(min-width: 400px) 400px, calc(100vw - 48px)&quot; src=&quot;https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/8tCyVELstYqtDFX3TunI.png?auto=format&quot; srcset=&quot;https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/8tCyVELstYqtDFX3TunI.png?auto=format&amp;w=200 200w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/8tCyVELstYqtDFX3TunI.png?auto=format&amp;w=228 228w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/8tCyVELstYqtDFX3TunI.png?auto=format&amp;w=260 260w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/8tCyVELstYqtDFX3TunI.png?auto=format&amp;w=296 296w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/8tCyVELstYqtDFX3TunI.png?auto=format&amp;w=338 338w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/8tCyVELstYqtDFX3TunI.png?auto=format&amp;w=385 385w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/8tCyVELstYqtDFX3TunI.png?auto=format&amp;w=439 439w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/8tCyVELstYqtDFX3TunI.png?auto=format&amp;w=500 500w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/8tCyVELstYqtDFX3TunI.png?auto=format&amp;w=571 571w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/8tCyVELstYqtDFX3TunI.png?auto=format&amp;w=650 650w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/8tCyVELstYqtDFX3TunI.png?auto=format&amp;w=741 741w, https://web-dev.imgix.net/image/MtjnObpuceYe3ijODN3a79WrxLU2/8tCyVELstYqtDFX3TunI.png?auto=format&amp;w=800 800w&quot; width=&quot;400&quot; /&gt;
&lt;/figure&gt;
&lt;p&gt;Formerly, Lighthouse would not be able to identify this problematic CLS behavior, though it would almost certainly show up in the experience of real users. Performance testing over scripted interactions improves lab fidelity significantly.&lt;/p&gt;
&lt;h2 id=&quot;looking-for-feedback&quot;&gt;Looking for feedback &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/lighthouse-user-flows/#looking-for-feedback&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The new user flow APIs in Lighthouse can do many new things, but it may still be complicated to measure the kind of scenarios your users encounter.&lt;/p&gt;
&lt;p&gt;Please reach out with any questions in the Lighthouse &lt;a href=&quot;https://github.com/GoogleChrome/lighthouse/discussions&quot; rel=&quot;noopener&quot;&gt;discussion forums&lt;/a&gt;, and file any bugs or suggestions in the &lt;a href=&quot;https://github.com/GoogleChrome/lighthouse/issues&quot; rel=&quot;noopener&quot;&gt;issue tracker&lt;/a&gt;.&lt;/p&gt;
</content>
    <author>
      <name>Brendan Kenny</name>
    </author>
  </entry>
  
  <entry>
    <title>Monitor your web page&#39;s total memory usage with `measureUserAgentSpecificMemory()`</title>
    <link href="https://web.dev/monitor-total-page-memory-usage/"/>
    <updated>2020-04-13T00:00:00Z</updated>
    <id>https://web.dev/monitor-total-page-memory-usage/</id>
    <content type="html" mode="escaped">&lt;p&gt;Browsers manage the memory of web pages automatically. Whenever a web page
creates an object, the browser allocates a chunk of memory &amp;quot;under the hood&amp;quot; to
store the object. Since memory is a finite resource, the browser performs
garbage collection to detect when an object is no longer needed and to free
the underlying memory chunk.&lt;/p&gt;
&lt;p&gt;The detection is not perfect though, and it
&lt;a href=&quot;https://en.wikipedia.org/wiki/Halting_problem&quot; rel=&quot;noopener&quot;&gt;was proven&lt;/a&gt; that perfect detection
is an impossible task. Therefore browsers approximate the notion of &amp;quot;an object
is needed&amp;quot; with the notion of &amp;quot;an object is reachable&amp;quot;. If the web page cannot
reach an object via its variables and the fields of other reachable objects,
then the browser can safely reclaim the object. The difference between these
two notions leads to memory leaks as illustrated by the following example.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; object &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 literal-property property&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;token punctuation&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; &lt;span class=&quot;token literal-property property&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2000&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 function&quot;&gt;setInterval&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;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&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;object&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;a&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 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;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;Here the larger array &lt;code&gt;b&lt;/code&gt; is no longer needed, but the browser does not
reclaim it because it is still reachable via &lt;code&gt;object.b&lt;/code&gt; in the callback. Thus
the memory of the larger array is leaked.&lt;/p&gt;
&lt;p&gt;Memory leaks are &lt;a href=&quot;https://docs.google.com/presentation/d/14uV5jrJ0aPs0Hd0Ehu3JPV8IBGc3U8gU6daLAqj6NrM/edit#slide=id.p&quot; rel=&quot;noopener&quot;&gt;prevalent on the Web&lt;/a&gt;.
It is easy to introduce one by forgetting to unregister an event listener, by
accidentally capturing objects from an iframe, by not closing a worker, by
accumulating objects in arrays, and so on. If a web page has memory leaks,
then its memory usage grows over time and the web page appears slow and
bloated to the users.&lt;/p&gt;
&lt;p&gt;The first step in solving this problem is measuring it. The new
&lt;a href=&quot;https://github.com/WICG/performance-measure-memory&quot; rel=&quot;noopener&quot;&gt;&lt;code&gt;performance.measureUserAgentSpecificMemory()&lt;/code&gt; API&lt;/a&gt; allows developers to
measure memory usage of their web pages in production and thus detect memory
leaks that slip through local testing.&lt;/p&gt;
&lt;h2 id=&quot;legacy-api&quot;&gt;How is &lt;code&gt;performance.measureUserAgentSpecificMemory()&lt;/code&gt; different from the legacy &lt;code&gt;performance.memory&lt;/code&gt; API? &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/monitor-total-page-memory-usage/#legacy-api&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you are familiar with the existing non-standard &lt;code&gt;performance.memory&lt;/code&gt; API,
you might be wondering how the new API differs from it. The main difference is
that the old API returns the size of the JavaScript heap whereas the new API
estimates the memory used by the web page. This difference becomes
important when Chrome shares the same heap with multiple web pages (or
multiple instances of the same web page). In such cases, the result of the old
API may be arbitrarily off. Since the old API is defined in
implementation-specific terms such as &amp;quot;heap&amp;quot;, standardizing it is hopeless.&lt;/p&gt;
&lt;p&gt;Another difference is that the new API performs memory measurement during
garbage collection. This reduces the noise in the results, but it may take a
while until the results are produced. Note that other browsers may decide to
implement the new API without relying on garbage collection.&lt;/p&gt;
&lt;h2 id=&quot;use-cases&quot;&gt;Suggested use cases &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/monitor-total-page-memory-usage/#use-cases&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Memory usage of a web page depends on the timing of events, user actions, and
garbage collections. That is why the memory measurement API is intended for
aggregating memory usage data from production. The results of individual calls
are less useful. Example use cases:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Regression detection during rollout of a new version of the web page to catch new memory leaks.&lt;/li&gt;
&lt;li&gt;A/B testing a new feature to evaluate its memory impact and detect memory leaks.&lt;/li&gt;
&lt;li&gt;Correlating memory usage with session duration to verify presence or absence of memory leaks.&lt;/li&gt;
&lt;li&gt;Correlating memory usage with user metrics to understand the overall impact of memory usage.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;compatibility&quot;&gt;Browser compatibility &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/monitor-total-page-memory-usage/#compatibility&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&quot;wdi-browser-compat&quot;&gt;
  &lt;span class=&quot;wdi-browser-compat__label&quot;&gt;Browser support&lt;/span&gt;
  &lt;ul class=&quot;wdi-browser-compat__items&quot;&gt;
    &lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;chrome&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Chrome 89, Supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
      89
    &lt;/span&gt;
    &lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
    &lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;firefox&quot;&gt;
      &lt;span class=&quot;visually-hidden&quot;&gt;Firefox, Not supported&lt;/span&gt;
    &lt;/span&gt;
    &lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;no&quot; title=&quot;Not supported&quot; aria-label=&quot;Not supported&quot;&gt;
&lt;p&gt;&lt;/p&gt;&lt;/span&gt;
&lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
&lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;edge&quot;&gt;
&lt;span class=&quot;visually-hidden&quot;&gt;Edge 89, Supported&lt;/span&gt;
&lt;/span&gt;
&lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;yes&quot; title=&quot;Supported&quot; aria-label=&quot;Supported&quot;&gt;
89
&lt;/span&gt;
&lt;/li&gt;&lt;li class=&quot;wdi-browser-compat__item&quot;&gt;
&lt;span class=&quot;wdi-browser-compat__icon&quot; data-browser=&quot;safari&quot;&gt;
&lt;span class=&quot;visually-hidden&quot;&gt;Safari, Not supported&lt;/span&gt;
&lt;/span&gt;
&lt;span class=&quot;wdi-browser-compat__version&quot; data-compat=&quot;no&quot; title=&quot;Not supported&quot; aria-label=&quot;Not supported&quot;&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;/span&gt;
&lt;/li&gt;&lt;p&gt;&lt;/p&gt;
  &lt;/ul&gt;
  &lt;a class=&quot;wdi-browser-compat__link&quot; href=&quot;https://developer.mozilla.org/docs/Web/API/Performance/measureUserAgentSpecificMemory#browser_compatibility&quot; target=&quot;_blank&quot;&gt;Source&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;Currently the API is supported only in Chromium-based browsers, starting in Chrome 89. The
result of the API is highly implementation dependent because browsers have
different ways of representing objects in memory and different ways of
estimating memory usage. Browsers may exclude some memory regions from
accounting if proper accounting is too expensive or infeasible. Thus, results
cannot be compared across browsers. It is only meaningful to compare the
results for the same browser.&lt;/p&gt;
&lt;h2 id=&quot;using-performancemeasureuseragentspecificmemory&quot;&gt;Using &lt;code&gt;performance.measureUserAgentSpecificMemory()&lt;/code&gt; &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/monitor-total-page-memory-usage/#using-performancemeasureuseragentspecificmemory&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;feature-detection&quot;&gt;Feature detection &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/monitor-total-page-memory-usage/#feature-detection&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;performance.measureUserAgentSpecificMemory&lt;/code&gt; function will be unavailable or may
fail with a &lt;a href=&quot;https://developer.mozilla.org/docs/Web/API/DOMException#securityerror&quot; rel=&quot;noopener&quot;&gt;SecurityError&lt;/a&gt; if the execution environment does not fulfil
the security requirements for preventing cross-origin information leaks.
It relies on &lt;a href=&quot;https://developer.mozilla.org/docs/Web/API/WindowOrWorkerGlobalScope/crossOriginIsolated&quot; rel=&quot;noopener&quot;&gt;cross-origin isolation&lt;/a&gt;, which a web page can activate
by setting &lt;a href=&quot;https://web.dev/coop-coep/&quot;&gt;COOP+COEP headers&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Support can be detected at runtime:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;if&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;window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;crossOriginIsolated&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;performance.measureUserAgentSpecificMemory() is only available in cross-origin-isolated pages&#39;&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 punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&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;performance&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;measureUserAgentSpecificMemory&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;performance.measureUserAgentSpecificMemory() is not available in this browser&#39;&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 punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&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;let&lt;/span&gt; result&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; performance&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;measureUserAgentSpecificMemory&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 punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;error&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;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;error &lt;span class=&quot;token keyword&quot;&gt;instanceof&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DOMException&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; error&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;SecurityError&#39;&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;      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;The context is not secure.&#39;&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 punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&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;throw&lt;/span&gt; error&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 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;result&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;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;h3 id=&quot;local-testing&quot;&gt;Local testing &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/monitor-total-page-memory-usage/#local-testing&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Chrome performs the memory measurement during garbage collection, which means
that the API does not resolve the result promise immediately and instead waits
for the next garbage collection.&lt;/p&gt;
&lt;p&gt;Calling the API forces a garbage collection after some timeout, which is
currently set to 20 seconds, though may happen sooner. Starting Chrome with the
&lt;code&gt;--enable-blink-features=&#39;ForceEagerMeasureMemory&#39;&lt;/code&gt; command-line flag reduces
the timeout to zero and is useful for local debugging and testing.&lt;/p&gt;
&lt;h2 id=&quot;example&quot;&gt;Example &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/monitor-total-page-memory-usage/#example&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The recommended usage of the API is to define a global memory monitor that
samples memory usage of the whole web page and sends the results to a server
for aggregation and analysis. The simplest way is to sample periodically, for
example every &lt;code&gt;M&lt;/code&gt; minutes. However, that introduces bias to the data because
memory peaks may occur between the samples.&lt;/p&gt;
&lt;p&gt;The following example shows how to
do unbiased memory measurements using a &lt;a href=&quot;https://en.wikipedia.org/wiki/Poisson_point_process&quot; rel=&quot;noopener&quot;&gt;Poisson process&lt;/a&gt;, which
guarantees that samples are equally likely to occur at any point in time
(&lt;a href=&quot;https://performance-measure-user-agent-specific-memory.glitch.me/&quot; rel=&quot;noopener&quot;&gt;demo&lt;/a&gt;, &lt;a href=&quot;https://glitch.com/edit/#!/performance-measure-user-agent-specific-memory?path=public%2Fmeasure-memory.js&quot; rel=&quot;noopener&quot;&gt;source&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;First, define a function that schedules the next memory measurement using
&lt;code&gt;setTimeout()&lt;/code&gt; with a randomized interval.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;scheduleMeasurement&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 comment&quot;&gt;// Check measurement API is available.&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;if&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;window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;crossOriginIsolated&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;performance.measureUserAgentSpecificMemory() is only available in cross-origin-isolated pages&#39;&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;    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;See https://web.dev/coop-coep/ to learn more&#39;&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;return&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 keyword&quot;&gt;if&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;performance&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;measureUserAgentSpecificMemory&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;performance.measureUserAgentSpecificMemory() is not available in this browser&#39;&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;return&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 keyword&quot;&gt;const&lt;/span&gt; interval &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;measurementInterval&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;  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 template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Running next memory measurement in &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;round&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;interval &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 interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; seconds&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&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 function&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;performMeasurement&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; interval&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;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;The &lt;code&gt;measurementInterval()&lt;/code&gt; function computes a random interval in milliseconds
such that on average there is one measurement every five minutes. See &lt;a href=&quot;https://en.wikipedia.org/wiki/Exponential_distribution#Random_variate_generation&quot; rel=&quot;noopener&quot;&gt;Exponential
distribution&lt;/a&gt; if you are interested in the math behind the function.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;measurementInterval&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;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;MEAN_INTERVAL_IN_MS&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt; &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;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;Math&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;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&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;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;MEAN_INTERVAL_IN_MS&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;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;Finally, the async &lt;code&gt;performMeasurement()&lt;/code&gt; function invokes the API, records
the result, and schedules the next measurement.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;performMeasurement&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 comment&quot;&gt;// 1. Invoke performance.measureUserAgentSpecificMemory().&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; result&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;    result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; performance&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;measureUserAgentSpecificMemory&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 punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;error&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;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;error &lt;span class=&quot;token keyword&quot;&gt;instanceof&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DOMException&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; error&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;SecurityError&#39;&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;      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;The context is not secure.&#39;&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;return&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 comment&quot;&gt;// Rethrow other errors.&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; error&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 comment&quot;&gt;// 2. Record the result.&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;Memory usage:&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; result&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 comment&quot;&gt;// 3. Schedule the next measurement.&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token function&quot;&gt;scheduleMeasurement&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 punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;Finally, begin measuring.&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Start measurements.&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;token function&quot;&gt;scheduleMeasurement&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;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;The result may look as follows:&lt;/p&gt;
&lt;div&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Console output:&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 literal-property property&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60_100_000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;  &lt;span class=&quot;token literal-property property&quot;&gt;breakdown&lt;/span&gt;&lt;span class=&quot;token operator&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 literal-property property&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;40_000_000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;attribution&lt;/span&gt;&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;br /&gt;        &lt;span class=&quot;token literal-property property&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;https://example.com/&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;token literal-property property&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Window&#39;&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;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 literal-property property&quot;&gt;types&lt;/span&gt;&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 string&quot;&gt;&#39;JavaScript&#39;&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;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20_000_000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;attribution&lt;/span&gt;&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;br /&gt;          &lt;span class=&quot;token literal-property property&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;https://example.com/iframe&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;          &lt;span class=&quot;token literal-property property&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token literal-property property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;iframe-id-attribute&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;token literal-property property&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;/iframe&#39;&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;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;          &lt;span class=&quot;token literal-property property&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Window&#39;&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;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 literal-property property&quot;&gt;types&lt;/span&gt;&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 string&quot;&gt;&#39;JavaScript&#39;&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;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100_000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;br /&gt;      &lt;span class=&quot;token literal-property property&quot;&gt;attribution&lt;/span&gt;&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 literal-property property&quot;&gt;types&lt;/span&gt;&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 string&quot;&gt;&#39;DOM&#39;&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;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;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;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;p&gt;The total memory usage estimate is returned in the &lt;code&gt;bytes&lt;/code&gt; field. This value is
highly implementation-dependent and cannot be compared across browsers. It may
even change between different versions of the same browser. The value includes
JavaScript and DOM memory of all iframes, related windows, and web workers in
the current process.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;breakdown&lt;/code&gt; list provides further information about the used memory. Each
entry describes some portion of the memory and attributes it to a set of
windows, iframes, and workers identified by URL. The &lt;code&gt;types&lt;/code&gt; field lists
the implementation-specific memory types associated with the memory.&lt;/p&gt;
&lt;p&gt;It is important to treat all lists in a generic way and to not hardcode
assumptions based on a particular browser. For example, some browsers may
return an empty &lt;code&gt;breakdown&lt;/code&gt; or an empty &lt;code&gt;attribution&lt;/code&gt;. Other browsers may
return multiple entries in &lt;code&gt;attribution&lt;/code&gt; indicating they could not distinguish
which of these entries owns the memory.&lt;/p&gt;
&lt;h2 id=&quot;feedback&quot;&gt;Feedback &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/monitor-total-page-memory-usage/#feedback&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&quot;https://www.w3.org/community/webperfs/&quot; rel=&quot;noopener&quot;&gt;Web Performance Community Group&lt;/a&gt; and the Chrome team would love
to hear about your thoughts and experiences with
&lt;code&gt;performance.measureUserAgentSpecificMemory()&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;tell-us-about-the-api-design&quot;&gt;Tell us about the API design &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/monitor-total-page-memory-usage/#tell-us-about-the-api-design&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Is there something about the API that doesn&#39;t work as expected? Or are there
missing properties that you need to implement your idea? File a spec issue on
the &lt;a href=&quot;https://github.com/WICG/performance-measure-memory/issues&quot; rel=&quot;noopener&quot;&gt;performance.measureUserAgentSpecificMemory() GitHub repo&lt;/a&gt; or add
your thoughts to a existing issue.&lt;/p&gt;
&lt;h3 id=&quot;report-a-problem-with-the-implementation&quot;&gt;Report a problem with the implementation &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/monitor-total-page-memory-usage/#report-a-problem-with-the-implementation&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Did you find a bug with Chrome&#39;s implementation? Or is the implementation
different from the spec? File a bug at &lt;a href=&quot;https://bugs.chromium.org/p/chromium/issues/entry?components=Blink%3EPerformanceAPIs&quot; rel=&quot;noopener&quot;&gt;new.crbug.com&lt;/a&gt;. Be sure to
include as much detail as you can, provide simple instructions for reproducing
the bug, and have &lt;strong&gt;Components&lt;/strong&gt; set to &lt;code&gt;Blink&amp;gt;PerformanceAPIs&lt;/code&gt;.
&lt;a href=&quot;https://glitch.com/&quot; rel=&quot;noopener&quot;&gt;Glitch&lt;/a&gt; works great for sharing quick and easy repros.&lt;/p&gt;
&lt;h3 id=&quot;show-support&quot;&gt;Show support &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/monitor-total-page-memory-usage/#show-support&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Are you planning to use &lt;code&gt;performance.measureUserAgentSpecificMemory()&lt;/code&gt;? Your public support
helps the Chrome team prioritize features and shows other browser vendors how
critical it is to support them. Send a tweet to &lt;a href=&quot;https://twitter.com/chromiumdev&quot; rel=&quot;noopener&quot;&gt;@ChromiumDev&lt;/a&gt;
and let us know where and how you&#39;re using it.&lt;/p&gt;
&lt;h2 id=&quot;helpful&quot;&gt;Helpful links &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/monitor-total-page-memory-usage/#helpful&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/WICG/performance-measure-memory&quot; rel=&quot;noopener&quot;&gt;Explainer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://performance-measure-user-agent-specific-memory.glitch.me/&quot; rel=&quot;noopener&quot;&gt;Demo&lt;/a&gt; | &lt;a href=&quot;https://glitch.com/edit/#!/performance-measure-user-agent-specific-memory?path=public%2Fmeasure-memory.js&quot; rel=&quot;noopener&quot;&gt;Demo source&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.chromium.org/p/chromium/issues/detail?id=1085129&quot; rel=&quot;noopener&quot;&gt;Tracking bug&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.chromestatus.com/feature/5685965186138112&quot; rel=&quot;noopener&quot;&gt;ChromeStatus.com entry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/WICG/performance-measure-memory/blob/master/ORIGIN_TRIAL.md#result-differences&quot; rel=&quot;noopener&quot;&gt;Changes since Origin Trial API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.chrome.com/origintrials/#/view_trial/1281274093986906113&quot; rel=&quot;noopener&quot;&gt;Concluded Origin Trial&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;acknowledgements&quot;&gt;Acknowledgements &lt;a class=&quot;headline-link&quot; href=&quot;https://web.dev/monitor-total-page-memory-usage/#acknowledgements&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Big thanks to Domenic Denicola, Yoav Weiss, Mathias Bynens for API design reviews,
and Dominik Inführ, Hannes Payer, Kentaro Hara, Michael Lippautz for code reviews
in Chrome. I also thank Per Parker, Philipp Weis, Olga Belomestnykh, Matthew
Bolohan, and Neil Mckay for providing valuable user feedback that greatly
improved the API.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://unsplash.com/photos/5tLfQGURzHM&quot; rel=&quot;noopener&quot;&gt;Hero image&lt;/a&gt; by &lt;a href=&quot;https://unsplash.com/@harrisonbroadbent&quot; rel=&quot;noopener&quot;&gt;Harrison Broadbent&lt;/a&gt; on &lt;a href=&quot;https://unsplash.com/&quot; rel=&quot;noopener&quot;&gt;Unsplash&lt;/a&gt;&lt;/p&gt;
</content>
    <author>
      <name>Ulan Degenbaev</name>
    </author><author>
      <name>Brendan Kenny</name>
    </author>
  </entry>
</feed>
