The Network Panel

🌐 Lesson 4 — The Network Panel

The Network panel records every HTTP request the browser makes — HTML, CSS, scripts, images, fonts, API calls — and shows you headers, response bodies, and a timing breakdown for each one. Press Ctrl + Shift + E to open it, then reload the page to capture the full load sequence.

🗺️ The Network Panel Interface

🚫 All HTML CSS JS XHR/Fetch Img ⚡ No throttling ▾ 💾
Status Method Domain File Type Size Time Waterfall
200 GET example.com / html 12 KB 143ms
200 GET example.com /style.css css 8.2 KB 88ms
304 GET example.com /app.js script 0 B 34ms
200 POST api.example.com /api/users json 2.1 KB 212ms
401 GET api.example.com /api/profile json 320 B 95ms
500 POST api.example.com /api/orders json 512 B 1.2s
6 requests  |  23 KB transferred  |  1.77s load  |  DOMContentLoaded: 231ms
💡 Open First, Then Reload The Network panel only captures requests made while it is open. Open it with Ctrl + Shift + E, then reload the page — otherwise you'll miss the critical HTML document request and everything that happened before you opened it.

🚦 HTTP Status Codes

The Status column is colour-coded. These are the codes you'll see most often in DevTools:

200
OK
Normal success — the request completed and returned data.
204
No Content
Success but no response body. Common for DELETE requests.
304
Not Modified
Browser used its cached copy. 0 B transferred — this is good.
401
Unauthorized
No valid credentials sent. Missing or expired auth token.
403
Forbidden
Credentials OK but access denied. Wrong role or permissions.
404
Not Found
The URL doesn't exist on the server. Wrong path or deleted resource.
429
Too Many Requests
Rate-limited by the server. Client is sending requests too fast.
500
Server Error
The server crashed or threw an exception. Check the Response tab for the error message.
301/302
Redirect
Browser was sent to a new URL. Check the Location response header.
ℹ️ 304 = Cache Working A 304 response with 0 B transferred means the browser had a cached copy and the server confirmed it was still fresh. Don't mistake this for an error — it's actually optimal. Seeing 200 on every load for the same static file means caching is misconfigured.

📋 Inspecting a Request — Headers Tab

Click any request to open the detail panel. The Headers tab shows what the browser sent and what the server replied with.

Headers
Response
Request
Cookies
Timings
Request Headers
Authorization:Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdW…
Content-Type:application/json
Accept:application/json, */*
Origin:https://example.com
Response Headers
Status:401 Unauthorized
Content-Type:application/json; charset=utf-8
WWW-Authenticate:Bearer error="invalid_token"
Access-Control-Allow-Origin:https://example.com

The key things to check in the Headers tab when an API call fails:

If you see…It means…
No Authorization in requestThe client isn't sending credentials — auth middleware isn't running
Authorization present but 401The token is expired, revoked, or signed with the wrong secret
401 with no Access-Control-Allow-OriginCORS is also failing — the browser may not even show you the 401
403 with valid tokenUser is authenticated but lacks the required role or permission
Location: header on a 301/302The server redirected — check if it's redirecting to HTTP instead of HTTPS

⏱️ The Timing Waterfall

Each bar in the Waterfall column is divided into colour-coded segments representing the phases of the HTTP lifecycle. Hover over any bar to see the exact milliseconds per phase.

0ms200ms400ms600ms800ms1000ms
DOMContentLoaded
Load
/ (HTML)
143ms
style.css
88ms
app.js (304)
34ms
/api/users
212ms
/api/orders
1.2s
DNS Lookup
TCP Connect
TLS Setup
Sending
Waiting (TTFB)
Receiving
DOMContentLoaded
Load event

TTFB (Time to First Byte) — the orange Waiting segment — is the server's processing time. A wide orange bar on /api/orders above tells you the server took 1.2 seconds to respond, not the network. Wide Receiving bars mean a large download; wide DNS/Connect bars mean connection setup isn't being reused.

📦 HAR Files — HTTP Archive

A HAR file (HTTP Archive) is a JSON snapshot of every network request in the Network panel — URLs, methods, headers, response bodies, cookies, and timing data — saved to a portable .har file you can share, replay, or analyse offline.

What a HAR File Looks Like

trace.har JSON • HTTP Archive 1.2
{
  "log": {
    "version": "1.2",
    "creator": { "name": "Firefox", "version": "125.0" },
    "pages": [{ "id": "page_1", "title": "https://example.com",
                  "pageTimings": { "onContentLoad": 231, "onLoad": 718 } }],
    "entries": [
      {
        "startedDateTime": "2024-11-14T09:31:00.000Z",
        "time": 143.2,
        "request": {
          "method": "GET", "url": "https://example.com/",
          "headers": [{ "name": "Authorization", "value": "Bearer eyJ…" }]
        },
        "response": {
          "status": 200, "statusText": "OK",
          "bodySize": 12288
        },
        "timings": {
          "dns": 8, "connect": 12, "ssl": 18,
          "send": 1, "wait": 91, "receive": 13
        }
      }
      // … one object per request
    ]
  }
}

Creating a HAR File in Firefox

  1. Open the Network panel (Ctrl + Shift + E).
  2. Reproduce the activity you want to capture — reload the page, complete the user flow, or trigger the API call that's failing.
  3. Right-click anywhere in the request list → Save All as HAR, or click the 💾 floppy disk icon in the toolbar.
  4. Save the .har file to disk.
💡 Capture the Full Page Load To capture the HTML document and all blocking resources, open the Network panel before reloading. If you need to capture a login flow across multiple page navigations, enable Persist Logs in the toolbar first — otherwise messages from page 1 are cleared when page 2 loads.

Reading and Importing a HAR File

You can replay a captured HAR file directly in Firefox's Network panel:

  1. Open the Network panel.
  2. Drag and drop the .har file onto the request list — or use the import icon in the toolbar if your Firefox version shows one.
  3. All captured requests appear in the list exactly as recorded. Click any row and inspect headers, response bodies, and timings as normal.

You can also read a HAR file programmatically — it's plain JSON:

import json with open('trace.har') as f: har = json.load(f) for entry in har['log']['entries']: req = entry['request'] resp = entry['response'] ttfb = entry['timings']['wait'] print(f"{resp['status']} {req['method']} {req['url']} (TTFB: {ttfb}ms)")

What HAR Files Are Used For

🤝
Sharing a Bug
Capture the exact requests and responses during a failure, send the HAR to a colleague or support team. They import it into their browser and see exactly what you saw — no access to your environment needed.
📊
Performance Analysis
Load into HAR Analyzer (toolbox.googleapps.com/apps/har_analyzer) for a visual waterfall, slowest requests flagged, uncompressed resources highlighted.
🔁
Before/After Comparison
Capture a HAR before an optimisation, then after. Compare total bytes, number of requests, and TTFB to confirm the improvement was real.
🐛
Intermittent Bugs
Ask users to capture a HAR during the failure and send it. The HAR contains the actual server response — including error messages — that their browser received.
⚠ Security Warning — HAR Files Contain Credentials

HAR files capture everything: session cookies, Bearer tokens, API keys in headers, and potentially sensitive data in response bodies. Before sharing a HAR outside your organisation, open it in a text editor and search for Authorization, Cookie, Set-Cookie, and token. Redact any values you find. Firefox does not automatically sanitise credentials on export.

💡 Practical Tips

🔍 Search Inside Responses Press Ctrl + F in the Network panel to search across the headers and response bodies of all recorded requests. Type a username, error code, or field name to find which request returned it — without clicking each one individually.
💡 Spotting Missing Compression Compare the Transferred and Size columns. If they're equal, the response was not compressed. Text resources (HTML, JSON, JS, CSS) should always show a smaller Transferred value — the server should send Content-Encoding: gzip or br.
💡 Blocking a Request Right-click any request → Block URL. On the next reload, the browser will refuse that URL. Use this to simulate a third-party script (analytics, ads, CDN) being unavailable — your page should still load and degrade gracefully.
💡 Throttle Before You Ship Set throttling to Regular 3G and reload. Loading states, skeleton screens, and error handling that never appear on a fast dev machine will show up clearly. Fix them before your users encounter them on mobile.

✏️ Exercises

  • Audit a page's requests. Open the Network panel on any site (Ctrl + Shift + E), reload, and note the total request count and bytes. Filter by XHR/Fetch — how many API calls does the page make?
  • Read an API response. Click a fetch or xhr request → Response tab. Read the JSON the server returned. Then click Headers and find the Content-Type response header.
  • Investigate a 304. Find a request with status 304 (look in the JS or image rows). Click it → Headers tab. Find the ETag or Cache-Control response header that tells the browser how long to cache this resource.
  • Read the timing breakdown. Click any external API request → Timings tab. Identify how long the Waiting (TTFB) phase was. Is most of the time spent waiting for the server or downloading the response?
  • Throttle and compare. Set the throttle dropdown to Regular 3G and reload. Note the new total load time. Do loading states appear? Set it back to No throttling.
  • Create a HAR file. Open the Network panel, reload a page, right-click the request list → Save All as HAR. Open the file in a text editor. Find the first entry in "entries" and read its "timings" object — what was the TTFB ("wait" value)?
  • Import the HAR. Drag the .har file you just saved back onto the Network panel request list. Confirm all requests are replayed and you can click them to inspect headers and responses.

📌 Key Takeaways

  • Open the panel before reloading — it only captures requests made while it's open.
  • XHR/Fetch filter isolates API calls — the first filter to use when debugging backend communication.
  • 304 = caching working correctly; 200 on every reload for a static file = broken cache headers.
  • The Response tab shows the actual server error message on 4xx/5xx — the status code alone is not enough.
  • The Waiting (orange) bar in the waterfall is TTFB — the server's processing time. A wide bar means a slow backend, not a slow network.
  • HAR files are portable JSON snapshots of the entire network trace — share, replay, or analyse them offline.
  • HAR files contain credentials — redact Authorization and Cookie headers before sharing externally.
  • Network throttling (Regular 3G) reveals loading states and performance issues invisible on a fast dev machine.
Up next
Lesson 5 — The Debugger Panel: breakpoints, stepping through JavaScript, watching variables, and diagnosing logic errors