Part 1 · 2 chapters · ~12 min

Network

DNS to WebSockets: the terms that decide how long before the first byte, which bytes are fetched at all, in what order, and what is reused from cache.

4

From URL to connection

The terms that decide how long before the first byte: resolving, connecting, the protocol, and the hints that move work earlier.

DNS resolution

browsercache?resolverISP / 1.1.1…root → T….comauthorit…A / AAAAanswer cached for its TTL at each hop

Turning a hostname into an IP address by asking a recursive resolver, which walks root, TLD and authoritative servers and caches the answer for its TTL.

in practiceThe "DNS" segment at the start of a Network waterfall row; dns-prefetch and preconnect hints; a slow first visit from a new country.

deep dive: Browser P1

TCP handshake

clientserverSYNSYN-ACKACKGET / (finally)1 RTT of nothing before the request

SYN, SYN-ACK, ACK: one round trip before a single byte of HTTP can be sent on a new connection.

in practiceThe "Initial connection" segment in the waterfall; why connection reuse and preconnect matter on high-latency mobile networks.

deep dive: Browser P1

TLS handshake

clientserverClientHello + key shareServerHello + cert + FinishedFinished + GETTLS 1.3: 1 RTT; 0-RTT on resumption

Agreeing keys and verifying the server's certificate before encrypted traffic flows; one round trip in TLS 1.3, two in 1.2.

in practiceThe "SSL" segment in the waterfall; certificate errors; why TLS 1.3 and session resumption cut first-byte time.

deep dive: Browser P1

RTT

office4G3Gsatellite600 ms RTThandshakes × RTT before the first byte

Round-trip time: how long a packet takes to reach the server and come back; the unit every handshake and request is paid in.

in practiceWhy a page that is fast in the office is slow in Lagos on 3G: every serial round trip multiplies the RTT.

deep dive: Browser P1

TTFB

DNSTCPTLSserverdownload370 msTTFB = everything until the first byte

Time to first byte: from the request starting to the first byte of the response arriving; DNS, connect, TLS and server think time combined.

in practiceThe first phase of LCP; the "Waiting for server response" bar in DevTools; server-side caching and CDNs move it.

HTTP/1.1

conn 1: a.jsconn 2: b.cssconn 3: c.pngconn 4: d.jsconn 5: e.pngconn 6: f.jsqueued: gqueued: h6 connections per origin; the rest queue

One request at a time per connection; browsers open about six connections per origin to get parallelism, and a slow response blocks the ones behind it.

in practiceDomain sharding and sprite sheets, both now anti-patterns; the "Stalled" segment when all six connections are busy.

deep dive: Browser P1

HTTP/2

stream 1htmlstream 3cssstream 5jsone TCPinterleaved…one lost packet still stalls every stream (TCP HoL)

Many requests multiplexed as streams over one TCP connection with compressed headers; head-of-line blocking moves down to TCP.

in practiceThe "h2" protocol column in Network; why bundling everything into one file matters less than it did.

deep dive: Browser P1

HTTP/3 and QUIC

HTTP/2 over TCPone loss stalls allTLS on top1-2 RTT setupHTTP/3 over QUICloss stalls one streamTLS built in1 RTT, 0-RTT resume

HTTP over QUIC, a UDP-based transport with TLS built in and per-stream loss recovery, so one lost packet stalls only its own stream.

in practiceThe "h3" protocol column; better tail latency on lossy mobile networks; connection migration when a phone switches from Wi-Fi to cellular.

deep dive: Browser P1

Head-of-line blocking

lost pktseq 7pkt 8waitingpkt 9waitingpkt 10waitingeverything behind waits for the retransmit

A slow or lost item at the front of a queue holding up everything behind it, at whichever layer the queue lives.

in practiceHTTP/1.1 response queues, TCP packet loss under HTTP/2, a render-blocking script in the HTML parser.

deep dive: Browser P1

Connection reuse (keep-alive)

clientoriginhandshakes (once)GET /aGET /bGET /cpay the setup once, reuse it

Keeping a connection open for further requests so the DNS, TCP and TLS costs are paid once per origin rather than per request.

in practiceThe "Connection ID" column in Network; why third-party origins cost more than their bytes.

deep dive: Browser P1

CDN

userLagosedgeLagos PoP: HITorigineu-west-1a hit never crosses the ocean

A network of edge servers near users that cache responses so most requests never travel to the origin.

in practiceThe "x-cache: HIT" response header; static assets with long cache lifetimes; edge functions running near users.

Preconnect

<link rel="preconnect" href="https://api.example.com"><!-- DNS + TCP + TLS start now, the fetch reuses the connection -->

A hint telling the browser to do DNS, TCP and TLS to an origin now, because a request to it is coming.

in practicelink rel=preconnect for the font or API origin; it saves the handshakes from the critical path.

deep dive: Browser P1
THE NETWORK LAYER, IN ORDER
every network term on this page, placed where it happens on the way from a URL to bytes
swipe the figure sideways, or tap expand for full screen
1/6
resolve
Resolve: the hostname becomes an address. DNS is a cache hierarchy; a CDN answers from the nearest edge so the next steps happen close to the user.
5

Hints, caching and channels

The terms that decide what is fetched at all, in what order, and what stays open.

Preload

htmlcssfont (late)font (preload)180 msdiscovered by the hint, not by the CSS

A hint to fetch a specific resource early at high priority because the page will need it, before the parser discovers it.

in practiceThe LCP hero image or a font referenced only from CSS; the console warning when a preloaded resource is not used within seconds.

deep dive: Browser P1

Fetch priority

requestpriorityhtml, cssHighestLCP img + fetchpriority=h…Highscript asyncLowimg below foldLowprefetchLowest

The browser's per-request priority (highest to lowest) and the fetchpriority attribute that nudges it.

in practiceThe Priority column in Network; fetchpriority="high" on the LCP image; low on below-the-fold carousels.

deep dive: Browser P1

Prefetch

page A idleprefetch B.jslowestclick → Bfrom cache

A low-priority fetch of something a likely next navigation will need, stored in the HTTP cache.

in practicelink rel=prefetch for the next route's chunk; Speculation Rules prerender for whole pages.

deep dive: Browser P10

HTTP cache

requestcache: f…max-ageyes: use…0 msno: reva…ETag

The browser's store of responses keyed by URL, reused according to Cache-Control so repeat requests skip the network.

in practiceThe "(disk cache)" and "(memory cache)" size column entries; hashed filenames with year-long max-age.

deep dive: Browser P8

Cache-Control

app.3f9a.jspublic, max-age=31536000, i…index.htmlno-cache/api/meprivate, no-store/feedmax-age=60, stale-while-rev…

The response header that says who may cache a response and for how long: max-age, no-cache, no-store, private, immutable, stale-while-revalidate.

in practiceimmutable, max-age=31536000 on hashed assets; no-cache on HTML; private on personalised API responses.

deep dive: Browser P8

ETag and revalidation

browserserverGET If-None-Match: "v7"304 Not Modified (no body)cheap on bytes, still one RTT

A version tag on a response; when stale, the browser asks "If-None-Match" and the server answers 304 with no body if unchanged.

in practiceThe 304 rows in Network: small, but each still a round trip.

deep dive: Browser P8

stale-while-revalidate

uicacheserverreadstale value nowrevalidate (background)fresh value stored

Serve the cached response immediately even if slightly stale, and refresh it in the background for next time.

in practiceCache-Control directive for feeds and config; the same idea in SWR and TanStack Query on the client.

deep dive: Browser P8 · React P8

CORS

app.comapi.comOPTIONS (preflight)Allow-Origin: app.comPOST /orders200 + Allow-Originthe browser enforces; the server opts in

Cross-Origin Resource Sharing: the server opting in, via Access-Control-Allow-* headers, to let another origin's script read its responses.

in practiceThe red CORS error in the console; preflight OPTIONS requests; "Script error." when a cross-origin script lacks it.

deep dive: Browser P9

Preflight

PUT + JSONnon-simpleOPTIONSallowed?real requestif yesan extra RTT unless Max-Age caches it

An automatic OPTIONS request the browser sends before a non-simple cross-origin request to ask whether it is allowed.

in practiceExtra OPTIONS rows before PUT, DELETE or JSON POSTs; Access-Control-Max-Age caches the answer.

deep dive: Browser P9

Compression (gzip, Brotli, zstd)

raw JSgzipbrotli600 KBparse cost is paid on the raw size

Encoding text responses smaller on the wire; Brotli beats gzip by 15 to 25% on JS and CSS.

in practicecontent-encoding: br in response headers; the two sizes in the Network size column (transferred vs resource).

deep dive: Browser P1

WebSocket

clientserverGET Upgrade: websocket101 Switchingprice ticksubscribeprice tick

A long-lived, full-duplex connection upgraded from HTTP, for messages in both directions without a request per message.

in practiceThe WS filter and Messages tab in Network; live prices, chat, presence; reconnect and backoff logic.

deep dive: Browser P1 · FSD P8

Server-Sent Events

clientserverGET Accept: text/event-streamdata: …data: …data: …one direction, reconnects itself

A one-way stream of text events from server to client over plain HTTP, with automatic reconnection built in.

in practiceEventSource; notification feeds and LLM token streaming; simpler than WebSocket when the client only listens.

deep dive: Browser P1 · FSD P8