Every web developer opens the Network tab. But most stop at checking status 200 and response size. The real debugging power is in the details you haven't looked at: the Waterfall, the Timing tab, and the hidden columns. I've spent hours fixing slow pages and broken caching, and the Network tab told me exactly what was wrong — I just had to know where to click.
This post covers the features I use daily: timing breakdowns, waterfall analysis, custom columns, request blocking, and response override. No fluff, just the stuff that actually saves time.
The Timing Tab: Where Your Time Goes
Click any request and open the Timing tab. You'll see a breakdown: DNS Lookup, TCP Connect, TLS Handshake (if HTTPS), Time to First Byte (TTFB), Content Download, and potentially others like Proxy Negotiation. This is the single most useful view for performance debugging.
I once had a page that took 8 seconds to load. The Network tab showed a single API call taking 7 seconds. The Timing tab revealed the TTFB was 6.5 seconds — the server was slow. Without the Timing tab, I'd have blamed the network. I checked the server logs and found a database query running a full table scan. Fixed in 20 minutes.
Another scenario: a request showing 2 seconds of 'Stalled' in the Waterfall. The Timing tab showed 'Queueing' and 'Stalled' stages. The culprit? Six parallel requests to the same domain hitting the browser's max connection limit (usually 6). The solution was domain sharding or HTTP/2 multiplexing.
Right-click the Waterfall column header and add 'Timing Breakdown' as a column to see a quick summary without clicking each request.
Reading the Waterfall
The Waterfall shows every request as a horizontal bar. The length is the total duration, and the color segments inside each bar represent different phases (DNS, TCP, TLS, TTFB, download). Hover over a request to see its start time and dependencies.
Dependencies are shown as thin lines connecting requests. For example, a CSS file might depend on an HTML file — the CSS request doesn't start until the HTML is parsed. This is critical for understanding render-blocking resources.
I debugged a site where images loaded after the page was visible — a 'flash of unstyled content' but with images. The Waterfall showed the images started only after a large JavaScript bundle finished loading. The JS was render-blocking because it was loaded in the <head> with no async or defer. Moving the script tag to the bottom fixed it.
<!-- Before: Render-blocking script in head -->
<script src="bundle.js"></script>
<!-- After: Async load -->
<script src="bundle.js" async></script>Custom Columns: The Hidden Data
By default, the Network tab shows Name, Status, Type, Initiator, Size, and Time. That's enough for basic debugging. But there's a lot more data hidden in the column list. Right-click any column header and choose 'Manage Columns' to see all available columns.
Here are the ones I always add:
- Domain: See which requests go to which origin, useful for identifying mixed content or unexpected third-party calls.
- Connection ID: Group requests sharing the same TCP connection. Under HTTP/1.1, multiple requests on the same connection are serial. Under HTTP/2, they're multiplexed. If you see many requests with the same ID on HTTP/2, something is misconfigured.
- Protocol: Shows 'h2' (HTTP/2), 'http/1.1', or 'http/2+quic/46'. If you see 'http/1.1' when you expect h2, your server isn't negotiating properly.
- Server IP Address: I once found a CDN routing to a different region because the IP was not what we expected.
- Cache-Control: See response caching headers at a glance. No need to open the Headers tab for every request.
Add the 'Connection ID' column to spot when a single TCP connection is being reused. Under HTTP/2, all requests to the same origin should share one connection. If you see multiple connections, it's a bug or misconfiguration.
Filtering and Preserving Logs
The filter bar is more powerful than typing keywords. You can use 'domain:', 'status-code:', 'mime-type:', 'larger-than:', and even negative filters like '-status-code:404'. Combine them: 'domain:api.example.com status-code:200'.
Preserve Log is a checkbox that keeps requests across page navigations. Critical for debugging redirect chains or service worker issues. I once debugged a redirect loop: a page kept redirecting to itself. With Preserve Log on, I saw the full chain of requests and noticed the server was sending a redirect header with an infinite loop. Without Preserve Log, the log would clear on each redirect and I'd see only the last request.
Another tip: Click the 'Clear' button (circle with slash) to clear the log, but hold down the mouse button for a second — it clears and starts recording again. Useful during live debugging.
Request Blocking for Testing
You can block specific requests to simulate failures. Right-click a request and select 'Block request URL'. The next page load will fail that request with a 'NET ERR_BLOCKED_BY_CLIENT' error. This is great for testing how your app handles missing assets or API failures.
I used this to test a site's fallback when Google Analytics was blocked (by ad blockers). Blocking the GA script showed me that the site threw an unhandled reference error. We added a simple guard and the site worked with or without GA.
// Guard against missing GA
if (typeof ga !== 'undefined') {
ga('send', 'pageview');
}Overriding Responses Locally
The Network tab allows you to override responses without touching the server. Go to the 'Overrides' tab (under the Network tab drawer), enable local overrides, and add a folder. Then, right-click a request, choose 'Override content', and edit the response. This is a lifesaver for testing API changes or mocking data.
I once needed to test how the frontend handled a 100 MB JSON response. The server wouldn't give me one. I overrode the response with a local file that had a huge JSON. Found the frontend crashed due to OOM — fixed with lazy loading.
Overrides only work for requests that match the file path. Ensure the local file structure mirrors the URL path. Also, overrides persist across sessions, so remove them when done.
Putting It All Together: A War Story
A production incident: users reported that our dashboard took 30 seconds to load. I opened DevTools and started with the Network tab. The Waterfall showed one large JavaScript chunk (2.5 MB) took 12 seconds to download, and another 5 seconds to parse. But the real issue was in the Timing tab: the TTFB for that chunk was 10 seconds — the CDN was cold-caching the file.
I added the 'Domain' column and noticed the JS was served from a different CDN endpoint than the other assets. That CDN didn't have pre-warming. We moved the chunk to the main CDN and added cache headers. Load time dropped to 4 seconds.
Without the Timing tab and custom columns, I'd have blamed the bundle size. But the real fix was infrastructure, not code.
TTFB on cold CDN cache for a large JS chunk — traced via Timing tab
Keyboard Shortcuts You Should Know
- arrow_rightCtrl+R (Cmd+R): Record/stop recording.
- arrow_rightCtrl+E (Cmd+E): Clear the log.
- arrow_rightCtrl+F (Cmd+F): Focus the filter box.
- arrow_rightHold Shift while clicking a request: Keep its details open while selecting another request.
- arrow_rightCtrl+Click (Cmd+Click): Open a request in a new tab.
The Network tab is the most underused tool in DevTools. Spend 30 minutes playing with these features on your own site — you'll find something you didn't expect. That's the point.
Frequently asked questions
How do I see the full timing breakdown for a request?
Click a request and go to the Timing tab. It shows DNS lookup, TCP connect, TLS handshake, TTFB (Time to First Byte), Content Download, and more. This helps pinpoint where the bottleneck is.
What is the Waterfall view useful for?
The Waterfall shows when requests started and ended relative to page load. By hovering over a request, you see its dependencies: which request blocked it (if any). This is critical for identifying render-blocking resources or sequential bottlenecks.
How do I add custom columns to the Network tab?
Right-click any column header (like 'Name' or 'Status'), choose 'Manage columns', and add columns like 'Domain', 'Connection ID', 'Protocol', 'Server IP Address', or 'Cache-Control'. These often surface issues invisible in default columns.