<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Thomas Seeley - tool</title><id>https://www.tseeley.com/tags/tool/atom.xml</id><updated>2024-12-15T00:00:00+00:00</updated><generator>tseeley.com</generator><link href="https://www.tseeley.com/tags/tool/atom.xml" rel="self" type="application/atom+xml"/><link href="https://www.tseeley.com" rel="alternate" type="text/html"/><subtitle>Posts about software and making things.</subtitle><entry><title>How to Use Chrome DevTools</title><id>https://www.tseeley.com/posts/how-to-use-chrome-devtools/</id><updated>2024-12-15T00:00:00+00:00</updated><author><name>Thomas Seeley</name></author><link href="https://www.tseeley.com/posts/how-to-use-chrome-devtools/" rel="alternate" type="text/html"/><published>2024-12-15T00:00:00+00:00</published><content type="html">
&lt;p&gt;I’ve been using DevTools for a while, but I often feel like I don’t really &lt;em&gt;know&lt;/em&gt; how to use all the tools. Or even all the tools that actually exist (there’s a lot)!&lt;/p&gt;
&lt;p&gt;Everything here is something I use already or wish I’d known about sooner. It’s mostly organized by what you’re trying to do, not by which panel it’s in.&lt;/p&gt;
&lt;section id=&quot;Getting-Around&quot;&gt;
&lt;h2&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#Getting-Around&quot;&gt;Getting Around&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;Command Menu.&lt;/strong&gt;&lt;/strong&gt; &lt;code&gt;Cmd + Shift + P&lt;/code&gt; opens it. It works like the &lt;a href=&quot;https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette&quot;&gt;VS Code command palette&lt;/a&gt;. Type what you want to do and it’ll find it.&lt;/p&gt;
&lt;figure&gt;
  &lt;img src=&quot;command-menu.png&quot; alt=&quot;The Command Menu&quot;&gt;
  &lt;figcaption&gt;The &lt;a href=&quot;https://developer.chrome.com/docs/devtools/command-menu&quot;&gt;Command Menu&lt;/a&gt;. &lt;code&gt;Cmd + Shift + P&lt;/code&gt; to open.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/open#files&quot;&gt;Quick open&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; &lt;code&gt;Cmd + P&lt;/code&gt; opens any file loaded by the page. If you know the filename you’re looking for, this is faster than navigating the Sources tree.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;Switch panels.&lt;/strong&gt;&lt;/strong&gt; &lt;code&gt;Cmd + ]&lt;/code&gt; and &lt;code&gt;Cmd + [&lt;/code&gt; move between panels. &lt;code&gt;Cmd + Shift + J&lt;/code&gt; goes straight to Console. &lt;code&gt;Cmd + Shift + C&lt;/code&gt; goes straight to element inspection mode.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/search&quot;&gt;Search across all files&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; &lt;code&gt;Cmd + Option + F&lt;/code&gt; searches every file loaded by the page. Useful for finding where a string, class name, or function is defined when you don’t know which file it’s in.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Elements-and-CSS&quot;&gt;
&lt;h2&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#Elements-and-CSS&quot;&gt;Elements and CSS&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;Inspect.&lt;/strong&gt;&lt;/strong&gt; &lt;code&gt;Cmd + Shift + C&lt;/code&gt; activates the selector, then click any element. Or right-click anything on the page and hit Inspect. You probably know this one.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;Force element state.&lt;/strong&gt;&lt;/strong&gt; Select an element, click the &lt;code&gt;:hov&lt;/code&gt; button in the Styles tab, and check &lt;code&gt;:hover&lt;/code&gt;, &lt;code&gt;:active&lt;/code&gt;, &lt;code&gt;:focus&lt;/code&gt;, or &lt;code&gt;:focus-within&lt;/code&gt;. The element stays in that state so you can inspect the styles without trying to keep your mouse in the right spot.&lt;/p&gt;
&lt;figure&gt;
  &lt;img src=&quot;force-state.png&quot; alt=&quot;Force element state panel&quot;&gt;
  &lt;figcaption&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/css/reference#force-state&quot;&gt;Force element state&lt;/a&gt;. Lock &lt;code&gt;:hover&lt;/code&gt;, &lt;code&gt;:active&lt;/code&gt;, &lt;code&gt;:focus&lt;/code&gt; without holding the mouse.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/dom&quot;&gt;Edit HTML live&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; Double-click any element in the Elements panel to edit its HTML. You can change text, attributes, add elements, whatever. Changes show up immediately.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/css/reference#change-declaration&quot;&gt;Edit CSS live&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; Click any CSS value in the Styles panel to change it. Click the property name to change that too. Add new properties by clicking the empty space at the bottom of a rule. Toggle any property on/off with the checkbox next to it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/css/reference#add-class&quot;&gt;Add a class&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; The &lt;code&gt;.cls&lt;/code&gt; button in the Styles panel lets you add or remove CSS classes from the selected element. Faster than editing the &lt;code&gt;class&lt;/code&gt; attribute by hand.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/css/reference#computed&quot;&gt;See computed styles&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; The Computed tab shows every CSS property actually applied to the element after cascade, inheritance, and specificity resolve. Click the arrow next to any property to jump to the rule that set it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;CSS specificity.&lt;/strong&gt;&lt;/strong&gt; Hover over a selector in the Styles tab to see its specificity score.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;Box model.&lt;/strong&gt;&lt;/strong&gt; The box model diagram at the bottom of the Styles tab (or top of Computed) is interactive. Double-click any value to change margin, padding, border, or dimensions.&lt;/p&gt;
&lt;figure&gt;
  &lt;img src=&quot;box-model.png&quot; alt=&quot;The box model diagram&quot;&gt;
  &lt;figcaption&gt;The interactive &lt;a href=&quot;https://developer.chrome.com/docs/devtools/css/reference#box-model&quot;&gt;box model&lt;/a&gt;. Double-click any value to edit it.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;Find unused CSS.&lt;/strong&gt;&lt;/strong&gt; &lt;code&gt;Cmd + Shift + P&lt;/code&gt;, type “Coverage”, click record, interact with the page. Red bars mean unused code, green means used. This tells you how much CSS (and JS) the page loads but never runs.&lt;/p&gt;
&lt;figure&gt;
  &lt;img src=&quot;coverage.png&quot; alt=&quot;Coverage panel showing used and unused code&quot;&gt;
  &lt;figcaption&gt;The &lt;a href=&quot;https://developer.chrome.com/docs/devtools/coverage&quot;&gt;Coverage panel&lt;/a&gt;. Red is unused, green is used.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/css/color&quot;&gt;Colors&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; Click any color swatch in the Styles panel to get a visual color picker. You can switch between hex, rgb, and hsl.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;Drag and reorder.&lt;/strong&gt;&lt;/strong&gt; You can drag elements in the DOM tree to reorder them. Useful for testing layout changes without editing code.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Console&quot;&gt;
&lt;h2&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#Console&quot;&gt;Console&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;code&gt;$0&lt;/code&gt; through &lt;code&gt;$4&lt;/code&gt;.&lt;/strong&gt;&lt;/strong&gt; &lt;code&gt;$0&lt;/code&gt; in the console references whatever element you have selected in the Elements panel. &lt;code&gt;$1&lt;/code&gt; is the previously selected element, and so on. I use &lt;code&gt;$0&lt;/code&gt; constantly.&lt;/p&gt;
&lt;figure&gt;
  &lt;img src=&quot;console-dollar-zero.png&quot; alt=&quot;Using $0 in the console&quot;&gt;
  &lt;figcaption&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/console/utilities#dom&quot;&gt;&lt;code&gt;$0&lt;/code&gt;&lt;/a&gt; references the currently selected element.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/console/utilities#querySelector&quot;&gt;&lt;code&gt;$(&apos;selector&apos;)&lt;/code&gt; and &lt;code&gt;$$(&apos;selector&apos;)&lt;/code&gt;&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; Shortcuts for &lt;code&gt;document.querySelector&lt;/code&gt; and &lt;code&gt;document.querySelectorAll&lt;/code&gt;. Only work in the console, not in page scripts.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/console/api#table&quot;&gt;&lt;code&gt;console.table()&lt;/code&gt;&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; Pass it an array of objects and it renders a sortable table. Way more readable than logging an array.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/console/api#time&quot;&gt;&lt;code&gt;console.time()&lt;/code&gt; / &lt;code&gt;console.timeEnd()&lt;/code&gt;&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; Wrap code between &lt;code&gt;console.time(&apos;label&apos;)&lt;/code&gt; and &lt;code&gt;console.timeEnd(&apos;label&apos;)&lt;/code&gt; to measure how long it takes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/console/api#group&quot;&gt;&lt;code&gt;console.group()&lt;/code&gt; / &lt;code&gt;console.groupEnd()&lt;/code&gt;&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; Creates collapsible groups in the console output. Useful for organizing noisy logging.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/console/api#trace&quot;&gt;&lt;code&gt;console.trace()&lt;/code&gt;&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; Logs a stack trace at whatever point you call it. Helpful for figuring out where a function is being called from.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/console/utilities#monitor&quot;&gt;&lt;code&gt;monitor(fn)&lt;/code&gt;&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; Logs every time a function is called, with its arguments. &lt;code&gt;unmonitor(fn)&lt;/code&gt; to stop. Only works for functions in global scope.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/console/utilities#copy&quot;&gt;Copy an object&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; &lt;code&gt;copy(obj)&lt;/code&gt; copies any JavaScript object to your clipboard as JSON. This one is easy to forget about.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;Filter messages.&lt;/strong&gt;&lt;/strong&gt; The filter bar at the top of the Console panel lets you filter by text, by level (errors, warnings, info), or by source. The “Selected context only” dropdown filters to the current iframe or worker.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/console/reference#persist&quot;&gt;Preserve log&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; Check “Preserve log” in Console settings to keep messages across page reloads. Invaluable when debugging redirect flows or page initialization.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Debugging-JavaScript&quot;&gt;
&lt;h2&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#Debugging-JavaScript&quot;&gt;Debugging JavaScript&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/javascript/breakpoints#loc&quot;&gt;Set a breakpoint&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; Sources panel, click a line number. The blue marker means execution will pause there. Click it again to remove it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;Conditional breakpoints.&lt;/strong&gt;&lt;/strong&gt; Right-click a line number, choose “Add conditional breakpoint,” enter a condition like &lt;code&gt;x &amp;gt; 10&lt;/code&gt;. Execution only pauses when the condition is true. Saves you from stepping through irrelevant iterations.&lt;/p&gt;
&lt;figure&gt;
  &lt;img src=&quot;conditional-breakpoint.png&quot; alt=&quot;A conditional breakpoint&quot;&gt;
  &lt;figcaption&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/javascript/breakpoints#conditional-loc&quot;&gt;Conditional breakpoints&lt;/a&gt;. Only pauses when your expression is true.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/javascript/breakpoints#exceptions&quot;&gt;Pause on exceptions&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; The pause icon in the Sources panel has a toggle for pausing on all exceptions or only uncaught ones. Useful for catching errors the moment they happen instead of hunting through the call stack.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/javascript/reference#stepping&quot;&gt;Step through code&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; Once paused:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;F10&lt;/code&gt; (step over) executes the current line and moves to the next
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;F11&lt;/code&gt; (step into) enters the function being called
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Shift + F11&lt;/code&gt; (step out) runs to the end of the current function and pauses in the caller
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;F8&lt;/code&gt; resumes execution
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/javascript/reference#watch&quot;&gt;Watch expressions&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; In the Sources panel sidebar, add expressions to the Watch section. They update every time execution pauses. Useful for tracking a variable across multiple breakpoints.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/javascript/reference#scope&quot;&gt;Local variables&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; The Scope section in the Sources panel shows every variable in scope when execution is paused. Local, closure, and global scopes are all visible.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/javascript/reference#format&quot;&gt;Pretty print&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; Click the &lt;code&gt;{}&lt;/code&gt; icon at the bottom of any minified file to format it. Makes third-party code readable enough to set breakpoints in.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/javascript/reference#ignore-list&quot;&gt;Blackbox scripts&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; Right-click a script in the Sources panel and choose “Add script to ignore list.” The debugger will skip over it when stepping. Useful for skipping framework internals.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/dom#event-listeners&quot;&gt;Debug event listeners&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; Elements panel, select an element, expand the “Event Listeners” tab. Shows every listener attached, with a link to the handler source. Check “Ancestors” to see listeners on parent elements.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Network&quot;&gt;
&lt;h2&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#Network&quot;&gt;Network&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;See all requests.&lt;/strong&gt;&lt;/strong&gt; The Network panel logs every request the page makes. Each row shows method, status, type, size, and timing. Click any request for details.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/network/reference#filter-type&quot;&gt;Filter by type&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; The filter bar has buttons for XHR, JS, CSS, Img, Media, Font, Doc, WS, and more. Click one to show only that type.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/network/reference#throttling&quot;&gt;Throttle network speed&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; The “No throttling” dropdown lets you simulate Slow 3G, Fast 3G, or custom speeds. Useful for testing how your site behaves on bad connections.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;Simulate offline.&lt;/strong&gt;&lt;/strong&gt; Check the “Offline” checkbox next to the throttling dropdown. The page can’t make any network requests.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/network/reference#disable-cache&quot;&gt;Disable cache&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; “Disable cache” checkbox at the top of the Network panel. Only active while DevTools is open. Forces fresh downloads of every resource.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;Request timing.&lt;/strong&gt;&lt;/strong&gt; Click a request, go to the Timing tab. Shows DNS lookup, TCP connection, TLS negotiation, time to first byte, and content download. The waterfall chart shows all of these visually for every request.&lt;/p&gt;
&lt;figure&gt;
  &lt;img src=&quot;network-timing.png&quot; alt=&quot;Network request timing breakdown&quot;&gt;
  &lt;figcaption&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/network/reference#timing&quot;&gt;Request timing&lt;/a&gt;. DNS, TCP, TLS, TTFB, and download broken out.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/network/reference#copy&quot;&gt;Copy as cURL&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; Right-click any request, Copy &amp;gt; Copy as cURL. Paste it in your terminal to replay the exact same request with all headers and cookies. Copy as fetch does the same for JavaScript.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/network/reference#block&quot;&gt;Block requests&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; Right-click a request, “Block request URL” or “Block request domain.” The page will behave as if that resource doesn’t exist. Good for testing graceful degradation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;Replay a request.&lt;/strong&gt;&lt;/strong&gt; Right-click a request, “Replay XHR.” Sends the exact same request again.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/network/reference#frames&quot;&gt;See WebSocket messages&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; Click a WebSocket connection in the Network panel, go to the Messages tab. Shows every frame sent and received.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;Export HAR.&lt;/strong&gt;&lt;/strong&gt; The download icon exports all network activity as a &lt;a href=&quot;&amp;lt;https://en.wikipedia.org/wiki/HAR_(file_format)&amp;gt;&quot;&gt;HAR file&lt;/a&gt;. You can share it or import it later for analysis.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Performance&quot;&gt;
&lt;h2&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#Performance&quot;&gt;Performance&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;Record.&lt;/strong&gt;&lt;/strong&gt; Performance panel, click record, interact with the page, stop recording. You get a flame chart showing exactly what the browser did: script evaluation, layout, paint, composite.&lt;/p&gt;
&lt;figure&gt;
  &lt;img src=&quot;flame-chart.png&quot; alt=&quot;Performance panel flame chart&quot;&gt;
  &lt;figcaption&gt;The &lt;a href=&quot;https://developer.chrome.com/docs/devtools/performance&quot;&gt;Performance panel&lt;/a&gt; flame chart. Script, layout, paint, and composite all visible.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;Find layout thrashing.&lt;/strong&gt;&lt;/strong&gt; Look for purple “Layout” bars in the flame chart. Click one to see the call stack that caused it. Common causes: reading &lt;code&gt;offsetHeight&lt;/code&gt; or &lt;code&gt;getBoundingClientRect&lt;/code&gt; then changing styles in a loop.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;Paint flashing.&lt;/strong&gt;&lt;/strong&gt; &lt;code&gt;Cmd + Shift + P&lt;/code&gt;, type “Show Rendering”, check “Paint flashing.” Green highlights appear wherever the browser repaints. Useful for catching unnecessary repaints.&lt;/p&gt;
&lt;figure&gt;
  &lt;img src=&quot;paint-flashing.gif&quot; alt=&quot;Paint flashing in action&quot;&gt;
  &lt;figcaption&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/rendering#paint-flashing&quot;&gt;Paint flashing&lt;/a&gt;. Green highlights wherever the browser repaints.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;Layout shift regions.&lt;/strong&gt;&lt;/strong&gt; In the same Rendering drawer, check “Layout Shift Regions.” Blue highlights show elements that shifted position, which directly causes &lt;a href=&quot;https://web.dev/articles/cls&quot;&gt;CLS (Cumulative Layout Shift)&lt;/a&gt; problems.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/rendering#fps&quot;&gt;FPS meter&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; &lt;code&gt;Cmd + Shift + P&lt;/code&gt;, type “Show FPS.” Gives you a real-time frames-per-second overlay.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;Web Vitals.&lt;/strong&gt;&lt;/strong&gt; The Performance panel has a Web Vitals lane that shows LCP, FID, and CLS events during the recording. Or run a Lighthouse audit for a full report.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;CPU throttling.&lt;/strong&gt;&lt;/strong&gt; The Performance panel has a CPU throttle dropdown (4x slowdown, 6x slowdown). Simulates a slower device.&lt;/p&gt;
&lt;/section&gt;
&lt;section id=&quot;Hidden-Power-Tools&quot;&gt;
&lt;h2&gt;&lt;a class=&quot;heading-anchor&quot; href=&quot;#Hidden-Power-Tools&quot;&gt;Hidden Power Tools&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/javascript/snippets&quot;&gt;Snippets&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; Sources panel &amp;gt; Snippets tab. Write JavaScript, save it, run it with &lt;code&gt;Cmd + Enter&lt;/code&gt;. Snippets persist across sessions. I keep a few for common debugging routines: clearing storage, logging all event listeners, dumping performance marks.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/overrides&quot;&gt;Local overrides&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; Sources panel &amp;gt; Overrides tab. Select a local folder, then edit any file in Sources. Your changes save locally and load instead of the server version on refresh. You can patch a production site without deploying.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/workspaces&quot;&gt;Workspaces&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; Sources panel &amp;gt; Filesystem tab. Add your project folder and DevTools links files to your local source. CSS changes in the Styles panel save directly to your &lt;code&gt;.css&lt;/code&gt; files. Persistent live editing.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;code&gt;monitor(fn)&lt;/code&gt; and &lt;code&gt;debug(fn)&lt;/code&gt;.&lt;/strong&gt;&lt;/strong&gt; &lt;code&gt;monitor(fn)&lt;/code&gt; logs calls. &lt;code&gt;debug(fn)&lt;/code&gt; sets a breakpoint on the first line of the function. Both only work in the console.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/overrides#override-headers&quot;&gt;Override response headers&lt;/a&gt;.&lt;/strong&gt;&lt;/strong&gt; Network panel &amp;gt; right-click a request &amp;gt; “Override headers.” Lets you test how your page reacts to different CORS headers, cache policies, etc. without changing the server.&lt;/p&gt;
&lt;/section&gt;

&lt;hr&gt;
&lt;p&gt;&lt;code&gt;web&lt;/code&gt; &lt;code&gt;tutorial&lt;/code&gt; &lt;code&gt;tool&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.tseeley.com/about/&quot;&gt;Thomas Seeley&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://bsky.app/profile/tseeley.com&quot;&gt;@tseeley.com on Bluesky&lt;/a&gt;, &lt;a href=&quot;https://mastodon.social/@iamseeley&quot;&gt;@iamseeley on Mastodon&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;larr; &lt;a href=&quot;https://www.tseeley.com/posts/we-forked-typescript/&quot;&gt;We forked TypeScript&lt;/a&gt; · &lt;a href=&quot;https://www.tseeley.com/posts/hello-membrane/&quot;&gt;Hello, Membrane&lt;/a&gt; &amp;rarr;&lt;/p&gt;
</content></entry></feed>