Console: Beyond console.log

console.table() for Arrays of Objects

Pass any array of objects to console.table() and the Console renders a sortable, formatted table — far more readable than the default expansion tree:

const users = [
  { id: 1, name: 'Alice', role: 'admin', lastLogin: '2026-06-01' },
  { id: 2, name: 'Bob',   role: 'user',  lastLogin: '2026-05-28' },
  { id: 3, name: 'Carol', role: 'user',  lastLogin: '2026-06-05' },
];
console.table(users);

// Show only specific columns:
console.table(users, ['name', 'lastLogin']);

console.group() for Structured Logging

console.group('Auth flow');
  console.log('Token received:', token.slice(0, 20) + '...');
  console.group('Decoded payload');
    console.log('sub:', payload.sub);
    console.log('exp:', new Date(payload.exp * 1000).toISOString());
  console.groupEnd();
console.groupEnd();

Use console.groupCollapsed() to start a group in collapsed state — useful for verbose logging that shouldn't flood the console by default.

console.time() and console.timeEnd()

console.time('data-fetch');
const data = await fetch('/api/items').then(r => r.json());
console.timeEnd('data-fetch'); // → data-fetch: 142.35ms

Live Expressions

Click the eye icon (Create live expression) in the Console toolbar and type any JavaScript expression. It evaluates continuously as the page runs — useful for watching a reactive variable without adding console.log calls everywhere:

// Examples that work as live expressions:
document.querySelectorAll('img:not([alt])').length   // accessibility check
performance.memory.usedJSHeapSize / 1048576 + ' MB'  // live memory usage
window.scrollY                                        // scroll position

Network Panel: Throttling, Replay, and HAR Export

Throttle to Simulate Real-World Conditions

The Network panel's throttle dropdown (default: "No throttling") includes presets for Fast 3G (1.5 Mbps down), Slow 3G (400 kbps), and Offline. You can add custom profiles with precise download, upload, and latency settings. Always test on Slow 3G before considering a feature done.

Block Individual Requests

Right-click any request → Block request URL (or domain). The request fails as a network error, letting you test error states without modifying code:

  • Block /api/recommendations to test the UI when that endpoint is down
  • Block an analytics domain to verify it degrades gracefully
  • Block a CDN to check local fallbacks

Replay XHR / Fetch Requests

Right-click any XHR or Fetch entry → Replay XHR. Re-triggers the exact request without refreshing the page. Saves significant time when debugging backend APIs during frontend work.

Export and Import HAR Files

HAR (HTTP Archive) files capture the full network log — request headers, response bodies, timing data. Export via the download icon at the top of the Network panel. The JSON-formatted file can be shared with backend engineers or analysed with third-party tools.

Sources Panel: Beyond Basic Breakpoints

Conditional Breakpoints

Right-click a line number → Add conditional breakpoint. Enter any JavaScript expression — the debugger only pauses when the expression evaluates to truthy:

// Only pause when processing the failing user ID
userId === 'usr_99999'

// Only pause on the 100th iteration of a loop
i === 99

// Only pause when the response is an error
response.status >= 400

Logpoints (Non-Pausing Breakpoints)

Right-click → Add logpoint. Prints a message to the Console when execution reaches that line, without pausing. Preferable to adding console.log directly because they don't touch the source file and disappear when DevTools closes:

// Logpoint message (uses same expression syntax):
"User data loaded:", JSON.stringify(user, null, 2)

Local Overrides

Sources → Overrides tab → Enable local overrides → choose a folder. DevTools intercepts requests and serves your local version of any file instead. Edit production CSS, JS, or JSON responses locally — changes persist across page reloads. Useful for: debugging minified production JS, testing CSS changes on a staging site, or mocking a specific API response.

Performance Panel: Read the Flame Chart

Press Ctrl+Shift+E (or click Record) then interact with the page. The flame chart shows the call stack over time. Key things to look for:

ColourMeaningAction
GreenPainting / compositingReduce layout thrash; use CSS transforms instead of top/left
YellowScripting (JS execution)Profile with Coverage; defer non-critical scripts
PurpleRendering (layout, style)Avoid forced synchronous layouts; batch DOM reads/writes
BlueLoading (network, parse)Preload critical resources; split large bundles

Coverage: Find Dead Code

Open the Command Menu (Ctrl+Shift+P) → type "Coverage" → Show Coverage. Load the page normally, then stop recording. The Coverage tab shows each JS and CSS file with a percentage of bytes used:

// A file showing 72% unused means:
// - 72% of bytes downloaded, parsed, and compiled are never executed
// - Good candidate for code splitting or tree-shaking
⌨️ Essential Keyboard Shortcuts
ActionMacWindows/Linux
Open DevTools++IF12
Command Menu+Shift+PCtrl+Shift+P
Search all sources++FCtrl+Shift+F
Inspect element+Shift+CCtrl+Shift+C
Toggle device toolbar+Shift+MCtrl+Shift+M
Step over (debugger)F10F10
Step into (debugger)F11F11

Application Panel: Storage and Service Workers

The Application panel provides direct access to everything the browser stores for your origin:

  • Local Storage / Session Storage — view, edit, and delete key-value pairs live
  • IndexedDB — browse databases, object stores, and individual records
  • Cookies — inspect, add, or delete cookies without touching the JS console
  • Service Workers — force update, bypass for network, and view cache storage contents
  • Cache Storage — see what your PWA or service worker has cached