Part 13 · 7 chapters · ~45 min

The DevTools Map

DevTools is a set of windows onto the engine, and each window faces one subsystem. This part is the map from subsystem to panel, how the whole thing works over a JSON protocol that scripts can speak too, the seven kinds of breakpoint and what each one answers, the console as an instrument, the panels most people have not opened, the chrome:// pages underneath, and a triage procedure from symptom to the panel that explains it.

126

The map: which panel watches which subsystem

the question

"I know what DevTools is. I do not know, for a given symptom, which panel to open first."

DevTools is a set of windows onto the pipeline from part 0. Each panel attaches to one or two stages. Knowing the attachment is what makes the first panel the right one. This part is the map; the DevTools course goes panel by panel in depth with a lab app built for it.

SubsystemPanel or paneWhat it exposesOpen it for
Network serviceNetworkRequests, priority, timing, headers, initiator chain, cache and SW hits, throttlingSlow TTFB, wrong priority, blocked requests, CORS, cookies not sent
HTML parserPerformance (Parse HTML), Network initiatorParse tasks, what the preload scanner startedRender-blocking discovery, late resources
DOMElements; Console ($0, $$); DOM breakpointsThe live tree, who changes itMarkup not as expected, mutation origin
Style engineStyles, Computed, Performance (Recalculate Style with selector stats)Cascade order, overridden rules, resolved values, selector costWhy this value, slow recalc
LayoutLayout pane, Elements overlays, Performance (Layout, forced reflow)Grid and flex geometry, box model, layout thrash with stacksWhy is it here, why is layout slow
Paint and compositorRendering tab, Layers, Performance (Paint, Composite, Frames)What repainted, layer tree and reasons, dropped framesJank, layer explosion, scroll stutter
Event loop and V8Performance (Main lane, Bottom-Up), Sources, ConsoleTasks, long tasks, functions by cost, breakpointsSlow interactions, blocked input, bugs
MemoryMemory, Performance monitorHeap snapshots, retainers, allocation timeline, live countsLeaks, GC pauses
Workers and SWSources (Threads), Application (Service Workers), Network (SW column)Worker debugging, SW lifecycle, SW-answered requestsWorker bugs, stale cache, update stuck
StorageApplicationEvery storage API, quota, clear and simulateData not persisting, quota, partition confusion
SecuritySecurity, Issues, Network headers, Application → FramesCertificates, mixed content, CSP and CORS violations, isolation statePadlock broken, blocked script, SAB unavailable
Navigation and lifecycleApplication (bfcache, Speculative loads), Network (Preserve log), Event listener breakpointsbfcache blockers, prerender state, lifecycle eventsBack is slow, prerender not firing
AccessibilityElements → Accessibility; full a11y tree; LighthouseRoles, names, the tree AT readsUnnamed controls, wrong roles
MediaMedia panelDecoder, buffered ranges, dropped frames, eventsStutter, no hardware decode
Everything in timePerformanceEvery thread, every event, with vitals and interactionsAny "why was that slow"
PANEL TO SUBSYSTEM
every DevTools panel is a window onto one part of the engine
swipe the figure sideways, or tap expand for full screen
1/7
the pipeline
The pipeline again: network, parse, style, layout, paint, composite, with the event loop running script throughout, and storage and security as cross-cutting services.
127

How DevTools works: the protocol

DevTools is a web application that asks the browser questions over a JSON protocol. Understanding that removes the mystery, explains what the panels can and cannot show, and opens the same door to scripts: Puppeteer, Playwright, Lighthouse and remote debugging all speak the Chrome DevTools Protocol.

the pieces
  1. Front end. TypeScript, in the Chromium repository under devtools-frontend. It renders in its own process (docked or undocked, it is a separate renderer). It is served from the browser's resources; you can also point Chrome at a custom build.
  2. Protocol. Domains (DOM, CSS, Network, Page, Runtime, Debugger, Profiler, HeapProfiler, Target, Emulation, Overlay, Storage, ServiceWorker, Tracing, and more). Each has commands (request and reply with an id) and events. The schema is published and versioned; the browser also exposes it at /json/protocol on a debugging port.
  3. Back end. In the browser process, agents for Network, Target, Browser. In each renderer, InspectorDOMAgent, InspectorCSSAgent, InspectorNetworkAgent and others in Blink, and V8's own inspector for Runtime, Debugger, Profiler and HeapProfiler. These hook directly into the engine: the Styles pane's "matched rules" is the style engine's own matching, run again for one element.
  4. Transport. An internal pipe when DevTools is attached in-process; a WebSocket when remote (--remote-debugging-port, or --remote-debugging-pipe for automation).
what follows from this
  1. Everything DevTools shows is scriptable. Puppeteer's page.evaluate is Runtime.evaluate; page.screenshot is Page.captureScreenshot; Lighthouse's traces are Tracing.start and the trace events.
  2. Some things DevTools shows are not free. Enabling the Network domain makes the browser record bodies; enabling Debugger changes V8's compilation (no lazy parsing in some cases); paint instrumentation slows rendering. An open DevTools is a different browser; close it when measuring.
  3. Remote debugging is the same protocol over USB: chrome://inspect for Android Chrome and WebViews; Safari's Web Inspector for iOS. The phone is where most performance bugs live; this is how you see them.
  4. The Protocol Monitor (Settings → Experiments) shows every message. Watch what the Styles pane asks when you select an element; then ask it yourself from a script.
  5. Other engines: Firefox DevTools uses the Remote Debugging Protocol; Safari uses the Web Inspector protocol; WebDriver BiDi is the cross-browser standard being built from both CDP and WebDriver.
HOW DEVTOOLS WORKS
the Chrome DevTools Protocol
swipe the figure sideways, or tap expand for full screen
1/6
a web app
The DevTools front end is a web page. It runs in its own renderer process (the DevTools window) and connects to the browser through a WebSocket or an internal pipe.
128

The debugger: seven kinds of breakpoint

Most people use line breakpoints and console.log. The debugger has six other ways to stop, each of which answers a "who did this" question that a line breakpoint cannot, because you do not know which line yet.

the kinds
  1. Line. Click the gutter. Pause before the statement.
  2. Conditional. Right-click the gutter, add a condition. Pause when true. For the 400th iteration or the one with the bad id.
  3. Logpoint. Same menu; prints an expression without pausing. A console.log you do not have to rebuild for, and that does not alter timing much.
  4. DOM. Elements → right-click → Break on: subtree modifications, attribute modifications, node removal. The debugger stops inside whatever code changed the node, through any framework.
  5. Event listener. Sources → Event Listener Breakpoints: categories of events (Mouse, Keyboard, Timer, Load, XHR, Animation, Control, Clipboard, DOM Mutation, Media, Pointer, Touch, Worker). Pause in the first handler for the ticked event. Who handles this click; who set this timer; who added an unload listener.
  6. XHR / fetch. Sources → XHR/fetch Breakpoints: URL substring. Pause where the request was issued, with the stack. Who hits this endpoint; why twice.
  7. Exception. The pause icon: uncaught, and optionally caught. Stops at the throw site with the live state. For "an error happens somewhere in the promise chain": tick caught exceptions and let it find the origin.
while paused
  1. Async stacks. The Call Stack includes the await, the setTimeout, the click that led here, as grey "async" frames. The answer to "how did we get into this callback".
  2. Scope and hover. Every variable in Local, Closure, Global; hover an identifier in the source for its value; edit a value in the console and continue.
  3. Restart frame. Rerun the current function from the top. Fix-and-retry without a reload.
  4. Ignore list. Mark node_modules and framework files as ignored; stepping skips them; stacks collapse them. The difference between stepping through your code and stepping through React.
  5. Live edit and Overrides. Edit a source file in Sources and save: V8 hot-swaps the function if its shape allows. Overrides: map a remote file to a local copy that persists across reloads; patch a third-party script or a production bundle to test a fix.
  6. Source maps. Served or inline; DevTools shows original source, breakpoints map both ways, stacks are symbolicated. Production builds should ship source maps to a restricted location (or upload to the error tracker) rather than none.
SEVEN KINDS OF BREAKPOINT
stopping the engine where the question is
swipe the figure sideways, or tap expand for full screen
1/7
line
Line breakpoint: click the gutter. Pauses before that statement, with scope, call stack (including async frames across awaits and timers), and a console in that frame.
129

The Console beyond log

the console as a tool
  1. Context selector. The dropdown at the top: run in the top frame, any iframe, any worker, the service worker, or an extension. Most "undefined is not a function" confusions in multi-frame pages are the wrong context.
  2. Utilities. $0 through $4 (the selected elements, most recent first), $(sel) and $$(sel), $x(xpath), inspect(obj), copy(obj), keys, values, monitor(fn) (log every call with args), monitorEvents(el, 'click'), getEventListeners(el), queryObjects(Ctor) (every live instance of a class: a leak probe), debug(fn) (break on entry).
  3. Formatting. console.table for arrays of objects; console.group and groupCollapsed; console.dir for a DOM node's properties rather than its markup; %o %s %d %c format specifiers; console.time / timeEnd; console.count; console.trace for a stack where you are; console.assert.
  4. Live expressions. The eye icon: an expression re-evaluated continuously. document.activeElement while tabbing; performance.memory.usedJSHeapSize while clicking.
  5. Filtering. By level, by text, by regex, by -url: negation; hide network messages; group similar; preserve log across navigations.
  6. Issues. The Issues panel is the structured version of console warnings: each with a description, the affected resources, and the fix. Cookies, CORS, CSP, mixed content, deprecations, accessibility.
what the console costs
  1. console.log of an object keeps a reference until the console is cleared: a leak detector that leaks.
  2. Logging in a hot path (scroll, rAF, mousemove) is itself a long task. Use a logpoint or a counter.
  3. Objects are shown live: the expanded view reflects the object's state when you expand it, not when it was logged. structuredClone or JSON.stringify for a snapshot.
130

The panels most people have not opened

PanelWhereWhat it doesWhen it is the answer
RenderingMore toolsPaint flashing, layout shift regions, layer borders, FPS meter, scrolling performance issues, emulate media (prefers-color-scheme, reduced-motion, print), vision deficiencies, disable local fonts, emulate focused pageJank, layer debugging, dark mode and print without changing OS settings, "does this work for deuteranopia"
LayersMore toolsThe compositor layer tree, 3D, with each layer's size, memory, and compositing reasonLayer explosion; GPU memory; "why does this element have its own layer"
Performance monitorMore toolsLive CPU, JS heap, DOM nodes, listeners, layouts and recalcs per secondLeak confirmation; "is layout happening on every scroll"
CoverageMore toolsPer file, bytes of JS and CSS used versus unused on this loadFinding dead code to split or drop; critical CSS extraction
Network conditionsMore toolsUser agent override, Accept-Language, throttling profiles, disable cacheTesting a UA-sniffed path; a language-negotiated page
SensorsMore toolsGeolocation override, orientation, idle state, touch emulationLocation-dependent features; device orientation
CSS OverviewMore toolsColours, fonts, unused declarations, contrast issues, media queries across the pageA design-system audit in one click
AnimationsMore toolsCaptures animations and transitions, scrubs, slows, shows easing curvesTuning a transition; seeing what animated when
ChangesMore toolsA diff of every style edit you made in DevToolsCopying a prototyped fix back into the codebase
RecorderMore toolsRecord a user flow, replay it, export as Puppeteer or Playwright, measure with PerformanceReproducing an interaction consistently for tracing
WebAudio / WebAuthn / MediaMore toolsAudio graph inspector; virtual authenticators; media element internalsEach one's domain
Device modeToolbar toggleViewport, DPR, touch, UA, throttling presets; device frames; media query barResponsive checks; but not a substitute for a real phone for performance
LighthouseTabLab audit with scores and pointers; also via CLI and CIA first pass; a checklist; a regression gate
131

chrome:// pages: the engine's own instruments

the ones worth knowing
  1. chrome://process-internals: which sites are in which process; site isolation mode; frame trees. The proof of parts 0 and 9.
  2. chrome://tracing and chrome://tracing with ui.perfetto.dev: the full tracing system DevTools' Performance panel is a view of. Record categories DevTools does not show (GPU, IPC, memory-infra, V8 internals, blink.user_timing, disabled-by-default-*). For a question the Performance panel cannot answer, this can.
  3. chrome://gpu: hardware acceleration status per feature (canvas, compositing, raster, video decode, WebGL, WebGPU), the GPU and driver, problems detected, and why a feature is software-only. The first stop for "video is using 60% CPU" and "canvas is slow on this machine".
  4. chrome://net-export: a full network log (NetLog) including DNS, sockets, TLS, HTTP/2 and QUIC frames, cache decisions. Load it in netlog-viewer. The Network panel's Timing tab is a summary of this.
  5. chrome://discards: tab lifecycle states; freeze and discard tabs on demand to test part 10's handling.
  6. chrome://serviceworker-internals: every registration, its version, running state, with Start, Stop, Unregister, and the console log of each worker.
  7. chrome://indexeddb-internals, chrome://quota-internals: per-origin storage sizes, open connections, and the quota calculation.
  8. chrome://histograms: Chrome's own UMA histograms, searchable, for the instance: e.g. PageLoad.PaintTiming.NavigationToLargestContentfulPaint2. The field metrics, locally.
  9. chrome://flags: experimental features; chrome://version: the command line it was launched with (check your flags took); chrome://memory-internals and the Task Manager (Shift+Esc): memory per process, per site, with GPU memory.
  10. about:blank? no; but view-source: and chrome://inspect/#devices for remote targets.
the lens on the lens
DevTools is a view over tracing, the protocol, and these internals pages. When a panel cannot answer a question, the layer under it usually can: Perfetto for timing, NetLog for the network, chrome://gpu for acceleration, the protocol for anything scriptable.
132

A triage procedure: symptom to panel

start from the symptom
  1. "The page is slow to appear." Network: document row Timing (TTFB?). Then Performance: Timings lane for FCP and LCP; the LCP phases; render-blocking requests in Insights.
  2. "It is visible but I cannot click anything." Performance: Main lane between FCP and the first interaction; long tasks; TBT. Usually script execution or hydration.
  3. "Clicking is laggy." Performance: Interactions lane; the phases; the handler in the Main lane. Then Bottom-Up by function.
  4. "Scrolling stutters." Rendering: Scrolling performance issues overlay (non-passive listeners); paint flashing (repaint on scroll); Performance: Frames lane and whether Main is busy during scroll; Layers for layer count.
  5. "An animation is janky." Rendering: paint flashing (should be none for a compositor animation); Performance: purple and green per frame means layout or paint is animating; Animations panel for the curve.
  6. "Things jump around while loading." Performance: Layout Shifts lane; click each; Rendering: Layout Shift Regions.
  7. "Memory grows." Performance monitor to confirm; Memory: three snapshots, compare, Detached filter, Retainers.
  8. "The style is wrong." Elements: Styles (crossed-out means overridden; the winner is uppermost), Computed with the "show all" and filter; Layout pane for grid and flex.
  9. "The request did not happen / was blocked / returned the wrong thing." Network: Preserve log on; the row's Headers, its Initiator, its Cookies tab; Console and Issues for CORS and CSP; Application → Service Workers for a stale SW; Network conditions to disable cache.
  10. "It works on desktop, not on the phone." Remote debug the phone (chrome://inspect); record a Performance trace there; check chrome://gpu on the device for acceleration.
  11. "It works for me, not for the user." Field data (CrUX, RUM) by device and connection; reproduce the condition with throttling and the user's state; then the above.
  12. "Who changed this / called this / set this." DOM breakpoint; XHR breakpoint; event listener breakpoint; monitor(fn); getEventListeners.
go to the lab

The DevTools course's lab app has a route for every row above, each with the pathology planted and the panel that reveals it. This part was the map; that course is the territory.