Browser DevTools Cheat Sheet
A guide to Chrome and Edge DevTools panels, console API methods, keyboard shortcuts, and network-tab techniques for debugging.
Core DevTools Panels
What each major panel is for.
- Elements- Inspect and live-edit the DOM tree and computed CSS styles
- Console- Run JavaScript, view logs/errors, interact with the page context
- Sources- Set breakpoints, step through code, view/edit files with the debugger
- Network- Inspect every request: headers, timing, payload, response, status code
- Performance- Record and profile CPU, rendering, and layout activity over time
- Application- Inspect storage: cookies, localStorage, IndexedDB, Service Workers, cache
- Lighthouse- Automated audits for performance, accessibility, SEO, and best practices
Useful Console API Methods
Beyond console.log — methods that speed up debugging.
console.log('info message');console.warn('warning');console.error('error');console.table([{ id: 1, name: 'Ada' }, { id: 2, name: 'Grace' }]); // renders as a tableconsole.group('User Details');console.log('Name: Ada');console.groupEnd();console.time('fetchData');await fetchData();console.timeEnd('fetchData'); // logs elapsed msconsole.assert(1 === 2, 'This logs because the assertion is false');console.trace(); // print the current call stack// $0 refers to the currently selected element in the Elements panel$0.style.border = '2px solid red';
Keyboard Shortcuts (Chrome/Edge)
The shortcuts worth memorizing.
Ctrl/Cmd + Shift + I Open DevToolsCtrl/Cmd + Shift + C Toggle element inspector (pick an element)Ctrl/Cmd + Shift + J Open Console directlyCtrl/Cmd + [ or ] Switch between DevTools panelsCtrl/Cmd + Shift + P Open the Command Menu (run any DevTools action)Ctrl/Cmd + Shift + M Toggle device/responsive modeF8 or Ctrl + \ Pause/resume script execution while debugging
Network Tab Tips
Getting more out of the Network panel.
- Disable cache- Check 'Disable cache' while DevTools is open to always fetch fresh assets
- Throttling- Simulate Slow 3G/Fast 3G to test performance on poor connections
- Filter by type- Filter requests by Fetch/XHR, JS, CSS, Img, WS to cut through noise
- Copy as cURL- Right-click a request → Copy → Copy as cURL to reproduce it in a terminal
- Waterfall timing- See DNS lookup, TCP handshake, TTFB, and download time per request
- Preserve log- Keep request history across page navigations/redirects for debugging
Profiling Long Tasks & Layout Thrashing
Use the Performance panel programmatically to mark and measure custom spans.
// Mark spans that show up as flame-chart entries in the Performance panelperformance.mark('render-start');renderList(items);performance.mark('render-end');performance.measure('render-list', 'render-start', 'render-end');// Read back measures programmatically (also visible under Timings track)const [entry] = performance.getEntriesByName('render-list');console.log(`render-list took ${entry.duration.toFixed(2)}ms`);// PerformanceObserver catches Long Tasks (>50ms) that block the main threadnew PerformanceObserver((list) => { for (const entry of list.getEntries()) { console.warn('Long task:', entry.duration, entry.name); }}).observe({ type: 'longtask', buffered: true });// Force a synchronous layout read to spot layout thrashing in the profiler// (interleaving reads/writes to offsetHeight causes forced reflow)el.style.height = '10px'; // writeconsole.log(el.offsetHeight); // read -> forces layout
Conditional Breakpoints, Logpoints & DOM Breakpoints
Break only on the iteration you care about, or when a specific node mutates.
// Right-click a line number in Sources -> 'Add conditional breakpoint...'// Expression is evaluated on every hit; execution pauses only when it's truthy:items[i].id === 4821 && retryCount > 2// Right-click -> 'Add logpoint...' — logs to Console WITHOUT pausing execution,// equivalent to a temporary console.log you never have to remove from source:`processing item ${item.id}, attempt ${retryCount}`// In Elements panel: right-click a node -> Break on ->// Subtree modifications (fires when children are added/removed/edited)// Attribute modifications (fires when an attribute changes, e.g. class toggling)// Node removal (fires right before the node is deleted)// Invaluable for tracking down 'who is removing/hiding my element' bugs
Finding Memory Leaks with Heap Snapshots
Compare two heap snapshots to isolate objects that should have been garbage collected.
// Memory panel workflow:// 1. Take snapshot #1 (baseline)// 2. Perform the suspected-leaky action (open/close a modal, navigate, etc.) several times// 3. Take snapshot #2, select 'Comparison' view against snapshot #1// 4. Sort by '# Delta' to see object types that grew and never shrank// Force a GC pass first (trash-can icon) so you're comparing real leaks, not// objects awaiting collection// From code: tag objects to make them easy to find in a snapshotwindow.__debugRefs = window.__debugRefs || new Set();__debugRefs.add(myComponentInstance); // search 'debugRefs' in the snapshot's 'Retainers' panel// Detached DOM nodes are the most common leak signature — filter the// snapshot's class list by 'Detached' to find nodes still referenced by JS// after being removed from the document
Lesser-Known Panels & Drawer Tools
Beyond the seven main panels — accessible via the Command Menu or the drawer (Esc key).
- Rendering tab- Paint flashing, layout shift regions, FPS meter, CSS media emulation, forced colors
- Coverage tab- Per-file byte breakdown of unused CSS/JS, refreshed on interaction to find dead code
- Animations tab- Scrub, slow down (25%/10%), and inspect keyframes of running CSS/Web Animations
- Issues tab- Aggregates CORS errors, deprecations, mixed content, and CSP violations with fix links
- Sensors tab- Override geolocation coordinates, device orientation, and idle detection state
- Network conditions- Override User-Agent and disable cache independently of the main Network tab toggle
- Memory panel timeline- 'Allocation instrumentation on timeline' records exactly which call sites allocate objects that survive
Use conditional breakpoints and logpoints in the Sources panel (right-click a line number) instead of sprinkling console.log or debugger statements through your source — you can add and remove them without redeploying code.