Concept
When you type https://example.com and press Enter, you trigger a chain of at least seven distinct steps before a single pixel appears. Knowing this chain cold is the baseline for debugging performance issues, security vulnerabilities, and production outages.
The seven-step sequence
User types URL
↓
1. Browser cache check
↓
2. DNS resolution (domain → IP address)
↓
3. TCP handshake (3-way: SYN → SYN-ACK → ACK)
↓
4. TLS handshake (for HTTPS, certificate, cipher negotiation)
↓
5. HTTP request (GET /path HTTP/1.1 with headers)
↓
6. Server processes & responds
↓
7. Browser parses HTML → fires sub-requests → rendersStep 1, Browser cache check
Before making any network request, the browser checks multiple caches in order:
- Memory cache, resources already in RAM from this session (fastest)
- Service worker cache, if a SW is registered, it intercepts the request
- Disk cache, previously fetched resources with valid
Cache-Controlheaders - Push cache, HTTP/2 server-pushed resources (short-lived, per-session)
If a valid cached response exists, the lifecycle ends here. This is why Cache-Control: max-age=31536000, immutable on static assets is so powerful, the browser never hits the network.
Step 2, DNS resolution
DNS converts a hostname to an IP address. The lookup follows a strict hierarchy:
Browser DNS cache
↓ (miss)
OS DNS cache (checked via /etc/hosts on Unix, registry on Windows)
↓ (miss)
Router / ISP resolver
↓ (miss)
Recursive resolver → Root nameserver → TLD nameserver → Authoritative nameserverA cold DNS lookup typically adds 20, 120ms. CDNs reduce this by placing authoritative nameservers close to users. dns-prefetch and preconnect hints let the browser resolve DNS early for known third-party origins.
Step 3, TCP handshake
TCP is connection-oriented, it guarantees ordered, reliable delivery. Before any data flows, a 3-way handshake establishes the connection:
Client → SYN → Server
Client ← SYN-ACK ← Server
Client → ACK → Server
[connection established]
Client → HTTP request → ServerThis costs 1 full round-trip before the first byte of request data. At 100ms RTT, that's 100ms wasted just opening the connection. HTTP/1.1 keep-alive, HTTP/2 multiplexing, and HTTP/3's QUIC protocol all exist partly to amortize this cost.
Step 4, TLS handshake (HTTPS only)
TLS adds 1, 2 more round trips on top of the TCP handshake for a new connection. The modern TLS 1.3 handshake:
Client → ClientHello (supported ciphers, TLS version, key share)
Client ← ServerHello + Certificate + Finished
Client → Finished
[encrypted channel established]TLS 1.3 reduces the handshake to 1-RTT (vs 2-RTT for TLS 1.2). TLS session resumption (0-RTT) can eliminate the handshake entirely for returning clients, though it carries replay-attack risk for non-idempotent requests.
Step 5 & 6, HTTP request/response
With the connection established, the browser sends an HTTP request:
GET /api/data HTTP/2
Host: example.com
Accept: application/json
Authorization: Bearer <token>
If-None-Match: "abc123" ← conditional request, might get 304 Not ModifiedThe server processes the request and returns a response with status, headers, and body. The Content-Type, Content-Encoding, and Transfer-Encoding headers govern how the browser reads the body.
Step 7, Parse and render
The browser doesn't wait for the full HTML. It streams and parses concurrently:
- HTML parser builds the DOM tree
- When a
<link rel="stylesheet">is encountered, CSS fetching/parsing blocks rendering - When a
<script>(withoutasync/defer) is encountered, HTML parsing pauses until the script downloads and executes - CSSOM + DOM → Render tree → Layout → Paint → Composite
This is why script placement and async/defer attributes matter: a blocking script in <head> delays the entire page.
Common Mistakes
1. Thinking a request only involves one round trip
Every new origin requires DNS + TCP + TLS (3, 4 RTTs) before the first byte. A page that loads from 10 origins multiplies that cost. Use preconnect for critical third parties.
<!-- Tell the browser to resolve DNS + open a connection early -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="dns-prefetch" href="https://analytics.example.com" />2. Not understanding that HTTPS is not just "HTTP + security"
TLS renegotiation, certificate validation, OCSP stapling, and cipher negotiation all add latency and CPU cost. This matters for time-to-first-byte (TTFB) analysis.
3. Confusing the browser cache with the CDN cache
The browser cache is private (per-user). A CDN cache is shared (edge nodes). A Cache-Control: private response is not cached by CDNs. A Cache-Control: public response can be. Getting this wrong leads to authentication bypasses or stale content served to everyone.
4. Not setting Connection: keep-alive (HTTP/1.1)
HTTP/1.1 defaults to keep-alive, but some server configs close connections aggressively. HTTP/2 makes this moot, multiplexing means all requests share one connection per origin.
5. Ignoring the Timing-Allow-Origin header
Third-party requests are opaque to PerformanceObserver. Without Timing-Allow-Origin: *, you can't see DNS/TCP/TLS breakdown for cross-origin resources in DevTools.
Best Practices
- Minimize origins. Each new origin costs 3, 4 RTTs before the first byte. Self-host critical fonts and scripts.
- Use HTTP/2 or HTTP/3. HTTP/2 multiplexing eliminates the per-resource connection cost. Verify your server supports it.
- Add
preconnecthints for known critical third-party origins (analytics, fonts, CDN). - Set cache headers deliberately. Immutable assets get
max-age=31536000, immutable. HTML getsno-cache(revalidate every time). Never omitCache-Controlon static assets. - Measure TTFB. It directly reflects DNS + TCP + TLS + server processing. Anything above 200ms deserves investigation.
- Use
103 Early Hintsif your server supports it, it lets the browser preload critical resources while the server is still generating the HTML response.
Performance Tips
- Cold DNS adds 20, 120ms per new origin. Measure with
performance.getEntriesByType("resource")[n].domainLookupEnd - .domainLookupStart. - TLS 1.3 + session resumption eliminates the TLS RTT for returning users. Verify on SSL Labs.
- HTTP/2 server push has largely been abandoned (Chrome removed it). Use
<link rel="preload">instead. - Target TTFB < 200ms. If TTFB is high, the problem is server-side (DB queries, cold start), no amount of frontend optimization helps.
- Connection coalescing in HTTP/2: if two domains resolve to the same IP and share a TLS certificate, the browser reuses one connection. CDN providers exploit this.
