Network TabWaterfallTTFBCachingDevTools

Network Tab & Waterfall Analysis

Learn how to read the Network tab waterfall, diagnose slow requests, understand caching headers, and optimize resource loading. The practical debugging skill every frontend engineer needs.

30 min read15 sections
01

Overview

The Network tab in Chrome DevTools shows every HTTP request the browser makes — HTML documents, stylesheets, scripts, images, API calls, fonts, and more. It's your window into what's loading, when, and how fast.

The waterfall chart visualizes these requests on a timeline, showing exactly when each resource starts loading, how long each phase takes (DNS, connection, TTFB, download), and which requests block others.

Together, they let you answer the most important performance question: why is this page slow? Whether it's a slow API, a massive image, a render-blocking stylesheet, or too many requests — the Network tab tells you exactly where the time goes.

The debugging mindset

When a page is slow, open the Network tab first. Sort by time, look at the waterfall, and find the longest bar. That's your bottleneck. Fix that one thing and re-test.

02

Introduction to Network Tab

The Network tab captures all network activity from the moment you open it. Every resource the page requests appears as a row with details about size, timing, status, and type.

How to Open It

Opening the Network Tabtext
macOS:  Cmd + Option + INetwork tab
Windows: F12 or Ctrl + Shift + INetwork tab

Pro tip: Check "Disable cache" to test without browser cache
Pro tip: Reload the page with the tab open to capture everything

Types of Resources

📄

Documents

HTML pages — the initial document and any iframes. This is the first request and everything else depends on it.

📦

Stylesheets & Scripts

CSS files (render-blocking) and JS bundles (parser-blocking). These directly impact how fast the page renders.

🔌

XHR / Fetch

API calls made by JavaScript. These fetch data for dynamic content — user info, product lists, dashboard data.

🖼️

Images & Media

JPG, PNG, WebP, SVG, video files. Often the largest resources on a page by total bytes.

🔤

Fonts

WOFF2, WOFF font files. Can cause invisible text (FOIT) if not loaded with font-display: swap.

🔗

Other

WebSocket connections, preflight CORS requests, service worker fetches, manifest files.

Quick overview stats

The bottom bar of the Network tab shows total requests, total transfer size, total resources size (uncompressed), DOMContentLoaded time, and Load time. These give you an instant health check of the page.

03

Understanding a Network Request

Click any request in the Network tab to see its full details. Every request has several tabs of information. Here's what each one tells you.

TabWhat It ShowsWhy It Matters
HeadersRequest URL, method, status code, request/response headersDebug CORS issues, check cache headers, verify API endpoints
PreviewFormatted response body (JSON, HTML, images)Quick check if the API returned expected data
ResponseRaw response body textSee exact payload, debug malformed responses
TimingDetailed timing breakdown (DNS, TTFB, download)Identify which phase of the request is slow
InitiatorWhat triggered this request (script, parser, redirect)Trace back to the code that made the request

Key Request Properties

Anatomy of a Network Requesttext
Request URL:    https://api.example.com/v1/products?page=1
Method:         GET
Status Code:    200 OK  (or 304 Not Modified if cached)
Remote Address: 104.26.10.78:443

── Request Headers ──────────────────────────────
Accept:          application/json
Authorization:   Bearer eyJhbGci...
Cache-Control:   no-cache

── Response Headers ─────────────────────────────
Content-Type:    application/json; charset=utf-8
Content-Length:   4,832
Cache-Control:   public, max-age=3600
ETag:            "abc123"
Content-Encoding: br  (Brotli compressed)

── Timing ───────────────────────────────────────
Queued:          2ms
DNS Lookup:      15ms
Initial Connection: 45ms (TCP + TLS)
Request Sent:    0.5ms
Waiting (TTFB):  120msserver processing time
Content Download: 8ms
Total:           190.5ms

HTTP Status Codes to Know

CodeMeaningWhat to Check
200OK — request succeededNormal. Check response body for expected data.
301/302Redirect — resource movedAdds a round-trip. Check if redirect is necessary.
304Not Modified — use cached versionGood! Means caching is working. Very fast response.
404Not Found — resource doesn't existWasted request. Remove the reference or fix the URL.
500Server Error — backend crashedCheck server logs. May cause high TTFB before failing.

Size column: two numbers

The Network tab shows two sizes: transferred (compressed, over the wire) and resource (uncompressed, in memory). If transferred is much smaller, compression is working. If they're the same, compression is missing — enable Brotli/Gzip on your server.

04

Waterfall Chart

The waterfall chart is the most important visualization in the Network tab. Each request is a horizontal bar on a shared timeline. The position shows when it started, the length shows how long it took, and the color segments show where time was spent.

Waterfall Chart Visualizationtext

Time (ms)  0    100      200    300    400    500    600    700
           │      │       │      │      │      │      │      │
index.html ████░░░░░░░░░░░│      │      │      │      │      │
           DNS  TTFB  DL  │      │      │      │      │      │
                          │      │      │      │      │      │
styles.css ───────────────██████░░░░░░░ │      │      │      │
           (waits for HTML)  TTFB  DL   │      │      │      │
                                        │      │      │      │
app.js     ───────────────██████████░░░░░░░░░░ │      │      │
           (waits for HTML)  TTFB    Download  │      │      │
                                               │      │      │
hero.jpg   ──────────────────────────────────████████░░░░░░░ │
           (waits for CSS/JS to finish)   TTFB   Download

api/data   ──────────────────────────────────────████░░░░░░░ │
           (waits for JS to execute)          TTFB  DL

Legend:  ██ = Active (DNS/Connect/TTFB)  ░░ = Download  ── = Waiting

Timing Breakdown (Hover Over Any Bar)

Hover over any waterfall bar to see the detailed timing breakdown. Each phase tells you something specific about where time is being spent.

PhaseWhat HappensSlow? Check This
QueueingRequest waits in browser queue (max 6 connections per origin)Too many requests to same origin. Use CDN or HTTP/2.
DNS LookupResolving domain name to IP addressNew domain? Add dns-prefetch. Usually 0ms for repeat visits.
Initial ConnectionTCP handshake + TLS negotiationNew origin? Add preconnect. HTTP/2 reuses connections.
SSLTLS certificate exchange and encryption setupPart of initial connection. Unavoidable for HTTPS.
Request SentBrowser sends the HTTP request bytesAlmost always <1ms. Not a bottleneck.
Waiting (TTFB)Time to First Byte — server processing timeSlow API? Backend issue. Optimize server, add caching.
Content DownloadReceiving the response bytesLarge file? Compress, resize images, code-split JS.
Timing Breakdown of a Single Requesttext

┌──────────────────────────────────────────────────────────┐
Total: 340ms
│                                                          │
│ ┌─────┐┌────┐┌──────────┐┌─┐┌──────────────┐┌────────┐   │
│ │Queue││DNS ││Connection││S││  TTFB (180ms)││Download│   │
│ │ 5ms ││15ms││  40ms    ││S││  ← Server    ││ 95ms   │   │
│ │     ││    ││ TCP+TLS  ││L││  processing  ││        │   │
│ └─────┘└────┘└──────────┘└─┘└──────────────┘└────────┘   │
│                                                          │
│ ⚠ TTFB is 53% of total timeoptimize the backend
└──────────────────────────────────────────────────────────┘

The two things to check first

TTFB (green bar) — if it's long, the server is slow. Optimize the backend, add server-side caching, or use a CDN. Content Download (blue bar) — if it's long, the file is too big. Compress it, resize images, or code-split JavaScript.

05

Identifying Bottlenecks

The waterfall tells a story about your page load. Here are the patterns that indicate performance problems.

Pattern 1: High TTFB (Slow Server)

High TTFB Patterntext
api/products  ──────────████████████████████████░░░
                        │← 800ms TTFB →│  DL
              
The green "Waiting" segment is huge.
   Server took 800ms to start responding.
   
Fix: Optimize database queries, add server caching,
     use a CDN for static content, add Redis for API responses.

Pattern 2: Large Downloads

Large Download Patterntext
bundle.js     ████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
              TTFB │←──── 2MB download over 3G ────────→│
              
The blue "Content Download" segment is huge.
   File is too large for the connection speed.
   
Fix: Code-split, tree-shake, enable Brotli compression,
     lazy-load non-critical modules.

Pattern 3: Request Waterfall (Sequential Loading)

Sequential Loading Patterntext
index.html    ████░░░
styles.css    ────────████░░░
  @import     ────────────────████░░░     ← discovered late!
  font.woff2  ────────────────────────████░░░  ← even later!
              
Each resource waits for the previous one.
   CSS @import creates a chain. Font discovered only after CSS.
   
Fix: Replace @import with <link> tags (parallel).
     Preload fonts: <link rel="preload" href="font.woff2" as="font">

Pattern 4: Too Many Requests (Connection Saturation)

Connection Saturation Patterntext
Request 1  ████░░░░
Request 2  ████░░░░
Request 3  ████░░░░
Request 4  ████░░░░
Request 5  ████░░░░
Request 6  ████░░░░
Request 7  ──────────────████░░░░   ← queued! waiting for slot
Request 8  ──────────────████░░░░   ← queued!
Request 9  ──────────────────────████░░░░  ← queued even longer

HTTP/1.1 allows max 6 connections per origin.
   Requests 7+ are queued until a slot opens.
   
Fix: Use HTTP/2 (multiplexing), bundle files, use a CDN
     (different origin = separate connection pool).

Sort by time to find the worst offender

Click the "Time" column header in the Network tab to sort requests by total duration. The slowest request floats to the top — that's your primary optimization target.

06

Request Prioritization & Loading

The browser doesn't load all resources equally. It assigns a priority to each request based on resource type, position in the document, and attributes. Understanding this helps you control what loads first.

ResourceDefault PriorityWhy
HTML documentHighestEverything depends on it. Must load first.
<link rel="stylesheet"> in headHighestRender-blocking. Browser can't paint without it.
<script> in head (no defer/async)HighParser-blocking. Stops DOM construction.
<link rel="preload">HighDeveloper explicitly marked as important.
<script defer>LowDownloads in parallel, executes after DOM.
<img> above the foldMediumVisible content, but not render-blocking.
<img loading="lazy">LowBelow the fold. Deferred until near viewport.
<link rel="prefetch">LowestFor future navigations. Fetched when idle.
Controlling Priorityhtml
<!-- ✅ Boost priority of hero image (LCP element) -->
<img src="hero.webp" fetchpriority="high" alt="Hero" />

<!-- ✅ Lower priority of below-fold image -->
<img src="footer-bg.webp" fetchpriority="low" loading="lazy" alt="" />

<!-- ✅ Preload critical font (discovered late by default) -->
<link rel="preload" href="/fonts/inter.woff2" as="font"
      type="font/woff2" crossorigin />

<!-- ✅ Preconnect to API origin (saves DNS + TCP + TLS) -->
<link rel="preconnect" href="https://api.example.com" />

Check priority in DevTools

Right-click the column headers in the Network tab and enable the "Priority" column. This shows the actual priority the browser assigned to each request. If your hero image is "Low" priority, add fetchpriority="high".

07

Filtering & Debugging

The Network tab can show hundreds of requests. Filtering helps you focus on what matters.

Filter by Resource Type

The filter bar at the top has buttons for each resource type. Click one to show only that type.

FilterShowsUse When
AllEvery requestOverview of full page load
Fetch/XHRAPI calls onlyDebugging API responses, slow endpoints
JSJavaScript filesFinding large bundles, checking code-splitting
CSSStylesheetsChecking render-blocking CSS, unused styles
ImgImagesFinding unoptimized images, missing lazy-load
FontWeb fontsChecking font loading, preload effectiveness
DocHTML documentsChecking redirects, initial document timing

Useful Debugging Techniques

Network Tab Power Featurestext
── Search ──────────────────────────────────────────
Cmd + F in Network tabsearch by URL, header, or response body
Example: search "products" to find all product API calls

── Block Requests ──────────────────────────────────
Right-click a request"Block request URL"
Test what happens if a resource fails to load

── Replay Request ──────────────────────────────────
Right-click a XHR/Fetch request"Replay XHR"
Re-send the exact same request without reloading the page

── Copy as cURL ────────────────────────────────────
Right-click"Copy as cURL"
Paste into terminal to reproduce the request outside the browser

── Preserve Log ────────────────────────────────────
Check "Preserve log" to keep requests across page navigations
Essential for debugging redirects and multi-page flows

── Override Headers ────────────────────────────────
Right-click"Override headers"
Test different cache headers or auth tokens without code changes

The filter search box

The text filter supports special syntax: status-code:404 finds failed requests, larger-than:100k finds large files, domain:api.example.com filters by origin, -domain:cdn.example.com excludes an origin.

08

Real Example Walkthrough

Let's walk through a real slow page load and diagnose it using the Network tab — the kind of analysis you'd do at work or in an interview.

Scenario: E-commerce Homepage Takes 5s to Load

Network Tab Waterfall (Slow Page)text
Time (ms)  0     500    1000   1500   2000   2500   3000   3500   4000   4500   5000
           │       │       │       │       │       │       │       │       │       │
index.html ██░░                                                                    
           80ms (OK)                                                               
                                                                                   
styles.css ────██████████░░░░░░░░░░░                                               
           ⚠ 350KB uncompressed! 900ms total                                      
                                                                                   
theme.css  ────────────────────────██████░░░░                                      
           ⚠ @import inside styles.csssequential! 400ms                        
                                                                                   
bundle.js  ────██████████████████████████████░░░░░░░░░░░░░░░░░░░░                  
           ⚠ 1.2MB bundle! 2.1s total. Parser-blocking.                          
                                                                                   
analytics  ────████░░░                                                             
           Blocking script in <head>. 200ms wasted.                               
                                                                                   
hero.jpg   ──────────────────────────────────────────────████████████░░░░░░░░░░░░░░
           ⚠ 4MB unoptimized JPG. Starts late (blocked by JS). 1.8s download.    
                                                                                   
api/products ──────────────────────────────────────────████████████████░░░          
TTFB: 800ms (slow backend). Starts after JS executes.               
                                                                                   
DOMContentLoaded: 2.8s    Load: 5.1s    Requests: 47    Transferred: 6.2MB

Diagnosis: 5 Problems Found

  • styles.css is 350KB uncompressed — no Brotli/Gzip compression enabled
  • theme.css loaded via @import — creates a sequential chain instead of parallel
  • bundle.js is 1.2MB — no code-splitting, no tree-shaking
  • analytics.js is a blocking script in <head> — delays everything
  • hero.jpg is 4MB — unoptimized, no WebP, no responsive sizes

The Fix

ProblemBeforeAfterSavings
CSS compression350KB (no compression)45KB (Brotli)~87% smaller
CSS @import chainSequential (900ms + 400ms)Two parallel <link> tags~400ms saved
JS bundle1.2MB single bundleRoute-based code-splittingInitial: ~200KB
Analytics scriptBlocking <script>Added asyncUnblocks parsing
Hero image4MB JPG120KB WebP + srcset + preload~97% smaller

After fixes: DOMContentLoaded ~800ms, Load ~1.5s, Transferred ~400KB. FCP improved from 2.8s to ~600ms.

The debugging process

(1) Sort by Size to find the biggest files. (2) Sort by Time to find the slowest requests. (3) Look at the waterfall for sequential chains. (4) Check the bottom bar for total requests and transfer size. Fix the biggest wins first.

09

Performance Optimization Techniques

Every optimization maps to something you can verify in the Network tab. Here are the techniques organized by strategy.

A. Reduce Number of Requests

✓ Done

Bundle Files

Combine multiple JS/CSS files into fewer bundles. Modern bundlers (Vite, webpack) do this automatically. Fewer requests = less connection overhead.

✓ Done

Remove Unused Assets

Use the Coverage tab to find unused CSS/JS. Remove dead code, unused libraries, and unnecessary third-party scripts. Every request costs time.

→ Could add

Inline Small Resources

CSS under 14KB can be inlined in the HTML to eliminate a round-trip. Small SVG icons can be inlined instead of loaded as separate files.

B. Optimize File Size

✓ Done

Enable Brotli/Gzip Compression

Server-side compression reduces text files (HTML, CSS, JS, JSON) by 60-80%. Brotli is ~15-20% better than Gzip. Check the Content-Encoding response header.

✓ Done

Minify CSS & JS

Remove whitespace, comments, and shorten variable names. Reduces file size by 20-40%. Build tools handle this in production mode.

→ Could add

Optimize Images

Use WebP/AVIF (30-50% smaller than JPG). Serve responsive sizes with srcset. Compress aggressively. Images are typically 50%+ of page weight.

C. Improve Loading Strategy

✓ Done

Code-Split JavaScript

Use dynamic import() to split bundles by route. Only load the JS needed for the current page. Verify in Network tab: initial bundle should be <200KB.

✓ Done

Lazy Load Below-Fold Images

Add loading='lazy' to images below the viewport. The browser won't fetch them until they're near the viewport. Verify: they shouldn't appear in initial waterfall.

✓ Done

Preload Critical Resources

Use <link rel='preload'> for fonts, hero images, and critical CSS. Moves them earlier in the waterfall. Verify: they should appear near the top.

D. API Optimization

→ Could add

Reduce API Payload Size

Return only the fields the client needs (GraphQL or sparse fieldsets). A 500KB JSON response that could be 50KB is wasting bandwidth and parse time.

→ Could add

Add HTTP Caching

Set Cache-Control headers on API responses. Cached responses show as '(disk cache)' or '(memory cache)' in the Network tab — 0ms TTFB.

→ Could add

Optimize Backend Response Time

High TTFB means the server is slow. Add database indexes, use Redis caching, optimize queries. Target: TTFB under 200ms for API calls.

10

Caching Insights

Caching is the single most effective performance optimization. A cached response loads in 0ms with 0 bytes transferred. The Network tab shows you exactly what's cached and what isn't.

Cache Headers

HeaderExampleWhat It Does
Cache-Controlmax-age=31536000Cache for 1 year. Browser won't re-request until expired.
Cache-Controlno-cacheAlways revalidate with server (still caches, but checks ETag).
Cache-Controlno-storeNever cache. Every request goes to the server. Use for sensitive data.
ETag"abc123"Content fingerprint. Browser sends If-None-Match to check if changed.
Last-ModifiedWed, 15 Jan 2025Timestamp. Browser sends If-Modified-Since to check freshness.

Memory Cache vs Disk Cache

Cache TypeIn Network TabSpeedWhen Used
Memory cache(memory cache)~0msResources from current session. Cleared on tab close.
Disk cache(disk cache)~1-5msPersisted to disk. Survives tab close and browser restart.
304 Not Modified304~50-100msServer confirmed cache is still valid. Only headers transferred.
No cache200 (full download)100ms+Full response downloaded. No caching benefit.
Optimal Caching Strategytext
── Static assets (JS, CSS, images with hash in filename) ──
Cache-Control: public, max-age=31536000, immutable
Cache forever. Filename hash changes on content change.
Example: app.a1b2c3.js, styles.x7y8z9.css

── HTML documents ─────────────────────────────────────────
Cache-Control: no-cache
Always revalidate. Ensures users get latest version.
Server returns 304 if unchanged (fast).

── API responses ──────────────────────────────────────────
Cache-Control: public, max-age=60, stale-while-revalidate=300
Cache for 60s. Serve stale for 5min while revalidating.
Good for data that changes but isn't real-time.

── Sensitive data (user profile, auth) ────────────────────
Cache-Control: private, no-store
Never cache. Always fetch fresh from server.

How to check in DevTools

Look at the "Size" column. If it says "(memory cache)" or "(disk cache)", the resource was served from cache — 0 bytes transferred. If it shows a byte count, it was downloaded from the server. Check the response headers for Cache-Control to understand why.

11

Advanced Insights

These advanced features help you simulate real-world conditions and get deeper insights from the Network tab.

📶

Network Throttling

Simulate Slow 3G (400Kbps), Fast 3G (1.5Mbps), or custom speeds. Reveals how your site performs on real mobile connections. Essential for testing.

🚫

Disable Cache

Check 'Disable cache' to force all requests to go to the server. Essential for testing first-visit performance. Only active while DevTools is open.

📋

Preserve Log

Keep network requests across page navigations and redirects. Essential for debugging login flows, OAuth redirects, and multi-page sequences.

🛑

Block Requests

Right-click → Block request URL/domain. Test what happens when a CDN is down, a third-party script fails, or an API is unreachable.

HAR File Export

Right-click in the Network tab → "Save all as HAR with content" to export the full network trace. Share it with teammates, attach to bug reports, or analyze in tools like WebPageTest. HAR files capture every request with full timing, headers, and response bodies.

Testing like real users

Enable "Slow 3G" throttling + "Disable cache" to simulate a first-time visitor on a mobile connection. This is the worst-case scenario your users experience. If it's fast here, it's fast everywhere.

12

Common Mistakes

These mistakes lead to slow pages and missed optimization opportunities.

📊

Ignoring the waterfall shape

Looking only at individual request times without seeing the overall pattern. A waterfall that's tall and narrow (sequential) is much worse than one that's short and wide (parallel).

Look at the waterfall shape first. Parallel is good, sequential chains are bad. Fix chains with preload, parallel <link> tags, and HTTP/2.

🔌

Too many API calls on page load

Making 10+ API calls on initial load, each waiting for the previous one. Common in SPAs that fetch user data, then permissions, then content, then preferences — all sequentially.

Combine related API calls into a single endpoint. Use GraphQL or BFF (Backend for Frontend) pattern. Parallelize independent requests with Promise.all().

🖼️

Unoptimized images

Serving 4MB hero images, using PNG for photos, not providing responsive sizes. Images are often 50-80% of total page weight.

Use WebP/AVIF, compress aggressively, serve responsive sizes with srcset, lazy-load below-fold images. Target: hero image under 200KB.

💾

Not using caching

Every request goes to the server because Cache-Control headers are missing or set to no-store. Repeat visitors download everything again.

Set max-age=31536000 for hashed static assets. Use no-cache (not no-store) for HTML. Add ETag for API responses.

🛑

Render-blocking resources in <head>

Multiple large CSS files and synchronous scripts in <head> that block rendering. The browser can't paint until all of them download and process.

Inline critical CSS, defer JS, load non-critical CSS async. Use the Coverage tab to find unused CSS/JS.

🔗

CSS @import chains

Using @import inside CSS files creates sequential download chains. The browser discovers each file only after downloading the previous one.

Replace @import with <link> tags in HTML. They download in parallel. Or bundle CSS at build time.

13

Interview Questions

Network and loading performance questions test your practical debugging skills. Interviewers want to hear a systematic approach with specific tools and metrics.

Q:How do you debug a slow network request?

A: Open the Network tab, find the slow request, and click it to see the Timing breakdown. Check TTFB — if it's high, the server is slow (optimize backend, add caching). Check Content Download — if it's high, the file is too large (compress, resize, code-split). Check Queueing — if it's high, too many requests are competing for connections (use HTTP/2, reduce requests).

Q:What is waterfall analysis and why is it important?

A: Waterfall analysis is reading the Network tab's timeline visualization where each request is a horizontal bar showing when it started and how long each phase took. It reveals sequential chains (resources waiting for others), connection saturation (too many requests), and the critical path (which resources block rendering). It's the primary tool for diagnosing page load performance.

Q:What is TTFB and how do you improve it?

A: TTFB (Time to First Byte) is the time between sending a request and receiving the first byte of the response. It measures server processing time. Improve it by: optimizing database queries, adding server-side caching (Redis), using a CDN for static content, enabling HTTP/2 server push, and reducing server-side computation. Target: under 200ms for API calls, under 100ms for static assets.

Q:How does the browser prioritize resource loading?

A: The browser assigns priority based on resource type and position. Highest: HTML document, CSS in <head>. High: synchronous scripts, preloaded resources. Medium: above-fold images. Low: deferred scripts, async scripts. Lowest: lazy images, prefetch. You can influence priority with fetchpriority='high'/'low', preload, defer, async, and loading='lazy'.

Q:What is the difference between preload, prefetch, and preconnect?

A: preload fetches a resource with high priority for the current page (fonts, hero images). prefetch fetches a resource at low priority for future navigations (next page's JS). preconnect establishes a connection (DNS + TCP + TLS) to a third-party origin early, saving 100-300ms when the actual request happens. Use preload for critical current-page resources, preconnect for third-party APIs/CDNs.

Q:How do you optimize page load using Network tab insights?

A: (1) Sort by Size — find and optimize the largest files (compress, code-split, resize images). (2) Sort by Time — find the slowest requests (optimize TTFB, reduce payload). (3) Read the waterfall — eliminate sequential chains (replace @import with <link>, preload fonts). (4) Check caching — ensure static assets have long max-age. (5) Check the bottom bar — reduce total requests and transfer size.

Q:Explain Cache-Control headers and their impact on performance.

A: Cache-Control tells the browser how to cache a response. max-age=N caches for N seconds without revalidation. no-cache always revalidates with the server (but still caches — returns 304 if unchanged). no-store never caches. immutable means the content will never change (used with hashed filenames). public allows CDN caching, private restricts to the user's browser. Proper caching can reduce repeat-visit load time by 80%+.

Q:What causes HTTP/1.1 connection saturation and how do you fix it?

A: HTTP/1.1 allows max 6 concurrent connections per origin. If a page makes 20+ requests to the same origin, requests 7+ are queued. Fix: upgrade to HTTP/2 (multiplexes unlimited requests over one connection), use a CDN (different origin = separate pool), bundle files to reduce request count, or domain-shard (spread across subdomains — last resort).

14

Practice Section

Apply your Network tab knowledge to these real-world scenarios.

1

Slow Page Load Debugging

A page takes 6 seconds to load. The Network tab shows 85 requests, 8MB transferred, and the waterfall is very tall with many sequential chains. How do you approach this?

Answer: Step 1: Sort by Size — find the biggest files. Likely unoptimized images (compress to WebP, add lazy loading) and a large JS bundle (code-split by route). Step 2: Sort by Time — find the slowest requests. Check TTFB for slow APIs. Step 3: Look at the waterfall for sequential chains — replace CSS @import with parallel <link> tags, preload fonts. Step 4: Check caching — add Cache-Control headers to static assets. Step 5: Reduce request count — bundle small files, inline critical CSS. Target: under 30 requests, under 1MB transferred.

2

Finding the Slow API

A dashboard page loads quickly but the data section takes 3 seconds to appear. The Network tab shows 4 XHR requests. How do you find which API is slow?

Answer: Filter by 'Fetch/XHR' to isolate API calls. Sort by Time to find the slowest one. Click it and check the Timing tab: if TTFB is high (e.g., 2.5s), the backend is slow — optimize the query, add caching, or paginate the response. If Content Download is high, the payload is too large — return only needed fields, paginate, or compress. Also check if the 4 requests are sequential (each waiting for the previous) — if so, parallelize with Promise.all().

3

CSS Blocking Rendering

Users see a white screen for 2 seconds before content appears. The Network tab shows a 400KB CSS file loading from a third-party CDN. Why is this happening and how do you fix it?

Answer: CSS is render-blocking — the browser won't paint until the CSSOM is complete. A 400KB CSS file from a third-party CDN adds DNS lookup + connection + TTFB + download time before any rendering. Fix: (1) Add <link rel='preconnect'> for the CDN origin to save connection time. (2) Inline critical above-the-fold CSS in a <style> tag. (3) Load the full CSS asynchronously with rel='preload' + onload swap. (4) Use the Coverage tab to find unused CSS rules — likely 60-80% is unused on this page.

15

Cheat Sheet (Quick Revision)

One-screen reference for Network tab debugging.

Quick Revision Cheat Sheet

First step: Open Network tab, disable cache, reload page. Look at waterfall shape.

TTFB: Time to First Byte. Server processing time. High = slow backend. Target: <200ms.

Content Download: Time to download response body. High = file too large. Compress or split.

Waterfall shape: Parallel (wide) = good. Sequential (tall) = bad chains. Fix with preload, <link>.

Sort by Size: Find largest files. Compress images (WebP), code-split JS, enable Brotli.

Sort by Time: Find slowest requests. Check TTFB vs download. Fix the biggest bottleneck.

Filter: Fetch/XHR: Isolate API calls. Find slow endpoints. Check payload size.

Cache-Control: max-age=31536000 for hashed assets. no-cache for HTML. no-store for sensitive data.

(memory cache): Served from RAM. 0ms. Current session only.

(disk cache): Served from disk. ~1-5ms. Persists across sessions.

304 Not Modified: Server confirmed cache is valid. Only headers transferred. Fast.

HTTP/2: Multiplexes requests over one connection. No 6-connection limit. Use it.

preload: Fetch critical resource early (fonts, hero image). High priority.

preconnect: Establish connection to third-party origin early. Saves 100-300ms.

Coverage tab: Shows unused CSS/JS per file. Red = unused. Remove or lazy-load.

Throttling: Test with Slow 3G + Disable cache = worst-case first visit.