booklore

High Performance Browser Networking

What Every Web Developer Needs to Know About Browser Networking

sufficient

reading path: overview → analysis → narration


overview

Overview

High Performance Browser Networking: What Every Web Developer Needs to Know About Browser Networking (2nd edition, 2021) by Ilya Grigorik is the book that connects every byte flowing across the wire to every pixel showing up on screen. Grigorik — a performance engineer at Google and one of the primary evangelists behind HTTP/2 adoption — writes with the rare authority of someone who helped alter the direction of web protocol design while still being a working engineer with production constraints.

This is not a networking textbook in the Kurose/Ross tradition. It is a practitioner's field guide: purpose-built for engineers who need to understand what actually happens when a browser types https:// and hits Enter. The book moves from the physical layer up through the rendering pipeline, naming each bottleneck, quantifying its cost, and showing how to eliminate it.


Executive Summary

| Part | Focus | Key Chapters | |------|-------|--------------| | 1. Building Blocks of Networks | Physical layer, Wi-Fi, cellular, bandwidth vs. latency | Building Blocks of Networks, Performance of Last-Mile Links | | 2. Transport Layer Protocols | TCP internals, UDP, TLS, latency bottlenecks | Transport Layer Protocols (TCP, UDP), Transport Layer Security (TLS) | | 3. Application Layer | HTTP/1.x, HTTP/2, server push, dependencies, prioritization | HTTP/1.x, HTTP/2, Optimizing for HTTP/2, HTTP/2 in the Wild | | 4. Next-Generation Transport | QUIC, HTTP/3, migration, 0-RTT | Building Blocks of QUIC, Introducing HTTP/3 | | 5. Real-Time & P2P | WebSocket, WebRTC, data channels, NAT traversal | WebSocket, WebRTC | | 6. Performance Optimization | Critical rendering path, caching, Resource Timing API | Wireless and Mobile Networks, Optimizing for Mobile Networks, Performance Analysis, Browser APIs |

The book's recurring argument: latency is the performance bottleneck of the web, and almost every protocol layer — if you understand it — offers a specific, actionable way to cut it.


Key Takeaways

  1. Latency, not bandwidth, is the bottleneck for web performance. A 100ms round-trip over a 10Mbps link delivers a small response faster than a 1GbE link with a 200ms round-trip. Every trip across the network costs more than the bytes being delivered.

  2. TCP is a sophisticated protocol with subtle defaults. Slow start, Nagle's algorithm, and delayed ACK are individually reasonable; together they produce hidden penalties. TCP Fast Open and increasing the initial congestion window are not academic tweaks — they change the shape of real page loads.

  3. TLS 1.3 is a performance breakthrough. Session resumption and 0- RTT cut the effective handshake cost. The cryptographic cost that made HTTPS feel slow in 2013 is largely gone. Serving over HTTP is now a correctness decision, not a performance one.

  4. HTTP/1.x creates its own waterfalls. The six-connections-per-origin browser limit and serial request-response pipelining mean each asset costs a full round trip. The DevTools network panel does not show bad code; it shows protocol-level serialization.

  5. HTTP/2 multiplexing changes the calculus. One connection per origin, many concurrent streams. Server push, stream prioritization, and header compression (HPACK) work against the same waterfall. The book covers framing, dependency trees, and real-world HTTP/2 caveats.

  6. QUIC and HTTP/3 solve the final TCP problem. TCP's head-of-line blocking means one lost packet stalls every stream on a connection. QUIC's per-stream loss recovery means one lost packet stalls only one HTTP/3 stream. UDP is the substrate; reliability, encryption, and reordering are done in user space.

  7. Rendering is the invisible final hop. Arriving bytes must be decoded, CSSOM assembled, DOM built, laid out, and painted. Render- blocking CSS, unoptimized JavaScript execution, layout thrashing, and inefficient repaints each introduce millisecond-scale pause that no network optimizations can fix.

  8. Wireless and mobile networks are qualitatively different. Wi-Fi retries, cellular RRC state machines, energy-aware radios, and SPDY multipath mean the same request on the same page can take very different paths to delivery. Optimizing for only wired broadband misses 70%+ of real traffic in many markets.


Who Should Read

| Reader Type | Why | |---|---| | Frontend engineers | Understand why your site feels slow in a way DevTools does not show | | Backend engineers | Optimize APIs and CDN caching for real mobile and wireless conditions | | DevOps / SREs | Run TLS termination, HTTP/2 reverse proxies, and HTTP/3 rollouts with eyes open | | Network engineers | Browser-side networking framing — DNS, TLS, TCP congestion from the application perspective | | Tech leads | Decide HTTP/2 vs HTTP/3, CDN strategy, and prerendering investments | | Mobile developers | Design for variable radio conditions and high-latency networks |


Who Should Skip

  • Software engineers with no interest in web performance — this is a specialized book, not general computer science
  • Readers seeking protocol spec details — this is a practitioner's guide, not an RFC compendium; follow the references for the modifiable-token JSON details
  • Anyone managing only non-web network infrastructure — the framing is browser-specific
  • Those looking for a JavaScript framework tutorial — there is no React, no Angular, no Vue; the focus is the network layer beneath them

Why This Book Matters

When the first edition appeared in 2013, HTTP/2 was not yet a standard and QUIC was a Google research project called SPDY. Grigorik wrote a book about protocols that did not yet exist, convinced that the problems they solved were real and urgent. He was right: HTTP/2 shipped six months after publication; Google shipped QUIC in Chrome and on YouTube; QUIC became IETF HTTP/3 in 2024.

The second edition (2021) earns its reprint. HTTP/3 is now spec, TLS 1.3 is standard, quiet mode and HTTP/3 adoption are making real traffic shifts, and WebRTC is production at scale. Grigorik's prose holds up because it is not about version numbers — it is about the principles of latency, head-of-line blocking, and the distance between user intent and rendered pixels.

The book is unusual in another way: Grigorik is an engineer, not a writer or journalist. Every section reflects work he did or problems he solved. The chapter on the TCP handshake is informed by real HTTP/2 deployments. The discussion of QUIC draws directly on early Chrome rollouts. This is not a tour of other people's research. It is a record of work done.


| Book | Author | Connection | |------|--------|------------| | Computer Networking: A Top-Down Approach | Kurose & Ross | The textbook version of the protocols Grigorik assumes | | TCP/IP Illustrated, Vol. 1 | Kevin Fall | Packet-level view of TCP and IP | | Web Scalability for Startup Engineers | Artur Ejsmont | The application and infrastructure layer above this book | | Site Reliability Engineering | Beyer et al. | Operational framing for running at the scale these protocols serve | | Designing Data-Intensive Applications | Martin Kleppmann | Distributed systems context for caching, replication, and CDN | | High Performance MySQL | Schwartz et al. | The database layer that connects the same network to persistent storage |


Final Verdict

High Performance Browser Networking is the book every web engineer should have read before they shipped their first production site, and the book they should re-read every time a new protocol appears. The 2nd edition brings QUIC and HTTP/3 the treatment they deserve and connects network behavior to something every engineer cares about: what the user actually sees.

It is dense, it is technically precise, and it moves quickly — but Grigorik's narrative voice keeps it human. The diagrams are worth the cover price alone.

Rating: 9.5/10 — The definitive practitioner's guide to browser networking. Required reading for frontend, backend, and platform engineers who care about real user performance.


content map

The Browser's Networking Stack

flowchart TB
    subgraph App["Application Layer"]
        APP["HTTP/1.1 | HTTP/2 | HTTP/3 | WebSocket | WebRTC"]
    end
    subgraph Transport["Transport Layer"]
        TCP["TCP<br/>(stream, reliable, ordered)"]
        UDP["UDP<br/>(datagram, unreliable, fast)"]
        QUIC["QUIC<br/>(UDP + reliability + encryption)"]
    end
    subgraph Network["Internet Layer"]
        IP["IPv4/IPv6"]
    end
    subgraph Link["Link Layer"]
        ETHERNET["Ethernet"]
        WIFI["Wi-Fi (802.11)"]
        CELL["Cellular (LTE, 5G)"]
    end

    APP --> TCP
    APP --> UDP
    APP --> QUIC
    TCP --> IP
    UDP --> IP
    QUIC --> IP
    IP --> ETHERNET
    IP --> WIFI
    IP --> CELL

Every byte leaving a browser passes through these layers on the way to the server, and back through them on the way to the screen. Understanding the behavior — and limits — of each layer is the entire argument of this book.


TCP: The Internet's Workhorse

The TCP Handshake

sequenceDiagram
    participant C as Client
    participant S as Server

    C->>S: SYN (seq=x)
    S->>C: SYN-ACK (seq=y, ack=x+1)
    C->>S: ACK (seq=x+1, ack=y+1)
    Note over C,S: Connection established — data can now flow

TCP requires one round trip just to establish the connection before any application data can be sent. In a browser opening six parallel connections to fetch assets, six handshakes serialize in the DevTools waterfall before you see a single response.

Slow Start: Why New Connections are Slow

flowchart LR
    A["New connection<br/>cwnd = 10 packets"] -->|"RTT 1"| B["cwnd doubles<br/>20 packets"]
    B -->|"RTT 2"| C["cwnd doubles<br/>40 packets"]
    C -->|"RTT 3"| D["cwnd doubles<br/>80 packets"]
    D -->|"RTT 4"| E["cwnd doubles<br/>reaches ssthresh"]
    E --> F["Congestion Avoidance<br/>(linear growth)"]

Every new TCP connection begins with slow start: the congestion window starts small (10 packets in modern OSes with an increased initial window, up from 1 in the original spec) and doubles each round trip. This means a fresh connection is structurally penalized. Reusing connections (keep-alive, HTTP/2) eliminates this cost entirely.

Nagle's Algorithm and Delayed ACK

Two separately reasonable TCP mechanisms interact badly with HTTP's request-response pattern:

  • Nagle's algorithm: when the sender has small messages, it waits a brief moment for more data to batch into a larger packet — unless an ACK arrives or the buffer fills.
  • Delayed ACK: the receiver waits up to 40ms to ACK, hoping the application will generate data to piggyback on the ACK.

In combination: the browser sends a small request, Nagle waits. The server receives it, sends a small response, delayed ACK waits. Both sides are waiting for the other to move first. This adds up to a 40ms penalty per request-response pair on many TCP stacks — often the hidden cost behind "why does this request take so long?"

Fixes: disable Nagle with TCP_NODELAY on the server, set TCP_QUICKACK on the client, or (best of all) use HTTP/2 multiplexing, which eliminates the small-pattern on a single connection.

TCP Fast Open

flowchart LR
    A["Standard TCP<br/>(SYN → SYN-ACK → ACK → data)"] -->|"1 RTT saved"| B["TCP Fast Open<br/>(SYN with data → SYN-ACK with ack + data)"]

TFO pushes application data into the initial SYN packet. The server can respond in the SYN-ACK. One round trip eliminated for connection establishment when the client has a valid TFO cookie. Requires OS and NAT support; not universally available as of 2026.

TCP Features the Book Covers in Depth

| Feature | Purpose | Impact on Web Performance | |---|---|---| | Slow start | Congestion control | New connections start slow; reuse beats new | | Nagle's algorithm | Reduce small packets | Adds latency with request-response traffic | | Delayed ACK | Reduce ACK packets | Interacts badly with Nagle for HTTP | | TCP Fast Open | Eliminate one RTT | Saves one round trip when cookie is available | | Selective ACK (SACK) | Identify lost blocks | Faster recovery from packet loss | | Window scaling | BDP > 64KB | Required for high-bandwidth, high-latency links | | TCP_CORK / TCP_NODELAY | Fine-grained send control | Server-side tuning for HTTP response framing |


UDP: The Fast and Loose Cousin

UDP is a datagram protocol: send a packet, hope it arrives. No ordering, no retransmission, no congestion control. Why does it matter?

Because TCP is structured to solve problems the web does not always have — or that the application wants to solve differently. For real-time media (audio, video, gaming), delayed delivery is worse than dropped delivery. You want the next frame, not last frame retransmitted.

flowchart LR
    A["TCP: Ordered, Reliable, Congestion-Controlled<br/>One lost packet stalls all streams"] -->
    B["UDP: Unreliable, Unordered<br/>Application decides what to do with loss"]

UDP is the substrate for QUIC, which adds back reliability and ordering per stream, plus TLS 1.3, using the space between the transport layer and the application — in user space, where innovation is not gated by OS kernel releases.


TLS: Security and Performance Combined

The Pre-TLS 1.3 Handshake

sequenceDiagram
    participant C as Client
    participant S as Server

    Note over C,S: TLS 1.2 handshake: 2 RTT minimum
    C->>S: ClientHello
    S->>C: ServerHello + Certificate + ServerKeyExchange
    C->>S: ClientKeyExchange + Finished
    S->>C: Finished + Application Data

TLS 1.2 required at least two round trips before any application data could flow. On a 50ms RTT mobile link, that was 100ms of pure protocol overhead — before the browser even started fetching the resource.

TLS 1.3: The Performance Revolution

sequenceDiagram
    participant C as Client
    participant S as Server

    Note over C,S: TLS 1.3 full handshake: 1 RTT
    C->>S: ClientHello + KeyShare
    S->>C: ServerHello + Certificate + Finished + Application Data

    Note over C,S: TLS 1.3 resumption: 0.5 RTT (session resumption)
    C->>S: ClientHello + SessionTicket + KeyShare
    S->>C: ServerHello + ServerFinished + Application Data

    Note over C,S: TLS 1.3 0-RTT data (with session ticket)
    C->>S: ClientHello + 0-RTT Application Data
    S->>C: ServerHello + Finished + Application Data

TLS 1.3 collapses the handshake to a single round trip. Session resumption goes to half a round trip (the server only ACK-style responds). 0-RTT data — using a session ticket from a previous handshake — can deliver application data in the first packet the client sends.

The key mechanisms: TLS 1.3 removes all insecure and unnecessary cipher suites. Key exchange defaults to ephemeral Diffie-Hellman (ECDHE); RSA key transport is gone. Session tickets with encrypted early data are the resumption path. The result is less CPU, fewer round trips, and more security.

TLS Performance Facts the Book Quantifies

| Scenario | TLS 1.2 | TLS 1.3 | Savings | |---|---|---|---| | Full handshake (new connection) | 2 RTT | 1 RTT | 50% fewer RTTs | | Session resumption | 2 RTT | 1 RTT | 50% fewer RTTs | | Session ticket (0-RTT) | N/A | 0 RTT (data in first packet) | One full RTT | | Cryptographic cost | RSA, AES-CBC | ECDHE, AES-GCM/ChaCha20-Poly1305 | Lower CPU, smaller messages |

DNS: The Foundation Every Byte Depends On

sequenceDiagram
    participant B as Browser
    participant OS as OS Resolver
    participant R as Recursive Resolver
    participant T as TLD Server
    participant A as Authoritative

    B->>OS: Resolve www.example.com
    OS->>R: A record?
    R->>T: .com NS record?
    T->>R: example.com NS record
    R->>A: example.com A record?
    A->>R: 93.184.216.34
    R->>OS: 93.184.216.34
    OS->>B: 93.184.216.34

A full cold DNS lookup requires visiting a TLD server and then an authoritative server — at minimum two round trips before any application protocol runs. The book covers how browser prefetch and OS-level caching eliminate this cost for connections the browser has seen recently.

| DNS Optimization | What It Does | |---|---| | OS and browser cache | Keeps popular records local; TTL governs freshness | | Preconnect / prefetch hints | rel="preconnect" and dns-prefetch trigger DNS before it is needed | | EDNS0 / larger UDP payloads | Reduces TCP fallback for large responses | | DNS over HTTPS (DoH) | Adds ~one RTT per lookup; trade-off with privacy and caching |


Wireless and Mobile Networks: The Real World

Bandwidth vs. Latency

The most important conceptual point in the book:

flowchart LR
    A["Bandwidth: how much<br/>data per second"] --> C["For small payloads:<br/>Latency dominates"]
    B["Latency: how long<br/>data takes to arrive"] --> C
    C --> D["10KB over 100ms RTT = 0.8s<br/>1GB over 200ms RTT = 8.3s<br/>Speed ratio: ~10x, time ratio: 1.03x"]

For the size of most web responses (tens to hundreds of kilobytes), the time of flight dominates the transfer time. Doubling bandwidth has negligible effect; cutting RTT by 50% has an immediate, visible effect.

Wi-Fi Retries and Hidden Stations

Wi-Fi uses CSMA/CA: listen before talk, exponential backoff on collision. The book quantifies retry overhead — at 50% packet loss, throughput collapses to ~10% of peak rate. This is the hidden cost of coffee-shop Wi-Fi and dense office environments.

Cellular Radio State Machines

stateDiagram-v2
    [*] --> DCH: Full data transfer
    [*] --> FACH: Short packet
    FACH --> DCH: Need more data
    DCH --> PCH: No traffic
    PCH --> DCH: Resume request
    PCH --> Idle: Timeout
    Idle --> DCH: New connection

    note right of DCH: Active state<br/>Worst power, lowest latency
    note right of FACH: Medium state<br/>Small packets only, higher latency
    note right of PCH: Idle-ish<br/>Network still aware of device
    note right of Idle: Best power, highest latency

The radio idle state is where real-world latency hides. When a phone's radio has been idle, the next network request must re-establish the RRC connection — adding 100–500ms that no CMS optimization can eliminate.

The book recommends: keep-alive pings, prefetch warm connections, and batch requests to avoid cycling the radio through idle repeatedly.


TCP Congestion Control: The Invisible Policeman

flowchart LR
    A["Sender"] -->|"Probes bandwidth"| N["Network"]
    N -->|"Implicit signal (no ACK)"| A
    A -->|"Signal: packet loss"| N
    A -->|"Cut cwnd in half"| A

TCP's congestion control is entirely implicit: the only loss signal is a missing ACK. The algorithm (CUBIC, the modern Linux default) has no knowledge of what happened in the network — only that something did not come back.

For HTTP, this matters because:

  1. Slow start means early data is slow
  2. Loss recovery cuts the window in half, triggering a cold start feeling
  3. Many small connections each wake slow start independently
  4. Reused connections accumulate window size beneficially — HTTP/2 exploits this directly

| Concept | Signal | Effect on Web Traffic | |---|---|---| | Slow start | Window doubles per RTT | Early data slow on new connections | | Congestion avoidance | Linear growth | Stabilizes but never fast-starts | | Loss recovery | Halve cwnd | Visible throughput dips on mobile/congested links | | RTT fairness | Long-RTT flows get less bandwidth | Satellites, Australia, constrained markets disadvantaged |


Key Lessons

  • TCP slow start shapes every new connection. Six parallel HTTP/1.1 connections each start slow; one HTTP/2 connection starts slow once and then benefits from cumulative window growth.
  • Nagle + delayed ACK is a 40ms tax on small HTTP requests. Disable Nagle on HTTP servers; set TCP_QUICKACK on HTTP/2 connections.
  • TLS 1.3 changes the calculus. Session resumption and 0-RTT make HTTPS feel faster than HTTP over TLS 1.2, and comparable to HTTP without TLS.
  • Bandwidth is abundant; latency is scarce. Optimize for RTT first, throughput second.
  • Wireless is not wired. Plan for retries, variable bandwidth, radio state transitions, and inherently unreliable media.
  • QUIC's per-stream recovery is the key insight. Losing one packet bottlenecks the entire HTTP/2 connection over a lossy link; QUIC loses only the affected stream.
  • DNS upfront cost compounds. Preconnect and prefetch eliminate waiting time the user never asked for — but abuse creates speculative traffic that the server pays for.

analysis

Strengths

  • The right level of detail. Grigorik is a working performance engineer who writes for working engineers. The book covers packet timing, congestion windows, and handshake sequence diagrams with enough depth to build intuition, but not so much RFC text that it reads like a protocol standard.
  • Connects every layer to user-observable performance. Unlike most networking books, this one consistently asks: "what does the user see?" The chain from TCP slow start to a blank white page is made explicit and quantified.
  • HTTP/2 treatment that survived its time. The first edition (2013) covered HTTP/2 before the RFC shipped and was accurate. The second edition's HTTP/3 and QUIC chapters land after the IETF spec finalized and demonstrate the same command of where the standard is heading.
  • Makes wireless mobile networks feel engineerable. The chapters on Wi-Fi retry behavior, cellular RRC state machines, and radio idle states provide mental models for engineers who previously felt mobile latency was random and untouchable.
  • Excellent code examples and browser DevTools walkthroughs. The PerformanceNavigationTiming and PerformanceResourceTiming API sections give engineers a concrete way to measure what the book describes.
  • Mermaid-quality diagrams. The packet timing diagrams, state machines, and network stack flowcharts are clean enough to photocopy into a design doc.
  • Credibility through authorship. Grigorik led Chrome's HTTP/2 outreach at Google and contributed directly to the standards bodies he describes. The book is not a journalist's reading of RFCs; it is a designer's field guide.
  • Section on TCP Fast Open and TCP_CORK. Rare in web-focused books but essential for anyone running a server that serves the HTTP handshake well.

Weaknesses

  • Some content aged between editions. The 2013 first edition covered SPDY as Google's experimental protocol extensively; the 2021 second edition rewrites it as HTTP/2 history. Readers with the first edition will find relevant content still there, but edition-specific references need care.
  • Less practical for Node.js/Go backend teams. The server-side TLS/QUIC configuration examples are lightweight. Engineers wanting a practical reference for running QUIC with nginx or caddy will need the upstream documentation.
  • The WebRTC chapter is a survey, not a deep dive. WebRTC deserves its own book (and has several). Grigorik covers the signaling problem, ICE/STUN/TURN, and the data channel API at a level adequate for a web performance book but insufficient for building a production calling app.
  • No coverage of HTTP/3 deployment trade-offs. The book explains QUIC and HTTP/3 well but underweights the operational cost: UDP often requires network operator buy-in, firewall adaptation, CDN infrastructure changes, and different observability tooling. Teams rolling out QUIC in 2026 have operational problems the book skims.
  • Performance Timing API detail is partial. The second edition covers navigationTiming and resourceTiming but the Navigation Timing Level 2 and the Paint Timing API are only touched briefly. This may be by design — the focus is the network stack — but browser engineers working on rendering performance will need additional reading.
  • Not enough on caching. The title is "Browser Networking," and the book honors that scope, but HTTP caching and CDN header strategy — often the single most impactful lever for real-user performance — get surprisingly thin treatment relative to their real-world impact.
  • No exercises or problems. This is a narrative practitioner's book, not a textbook. Engineers who learn best by building and measuring will want to supplement with hands-on tcpdump, wireshark, and Chrome Dev Tools experiments.

Criticism

The "Google-centric" Critique

Grigorik wrote this book from inside Google, and some sections reflect Google's infrastructure assumptions: QUIC as the default, Chrome's implementation as the reference, single-organization adoption as the model. QUIC was designed by Google engineers for Google problems before it became an IETF standard. The book's frame — "QUIC solves HTTP/2's head-of-line blocking problem" — is the Google frame. That critique is mostly historical now: QUIC is standard, the IETF process corrected some Google-specific design choices, and Grigorik's treatment is careful about distinguishing Google's original proposal from the shipped standard.

The "No CDN depth" Critique

A developer buying this book to understand how a CDN actually changes their site's network performance will find the CDN content thin (a single chapter in the first edition, less in the second). CDNs are where most real-world TLS and HTTP/2 work happens at scale. The book covers the protocol correctly — CDNs just happen to implement it. Engineers working specifically on CDN strategy or Varnish/nginx/HAProxy configuration will want supplemental reading.

The "Protocol spec, not deployment" Risk

The book explains HTTP/2 and HTTP/3 correctly but skips deployment failure modes: ALT-SVC misconfiguration, HTTP/3 fallback behavior when a server is unreachable on UDP, middlebox interference with QUIC's long headers, and certificate management under fast rollover. These are active research topics in 2026 and cut against the book's practical framing.

The "Caching Underweighted" Critique

As a practical matter, many teams reading this book want to optimize their site for real users. The book's treatment of HTTP caching rules, Cache-Control directives, CDN header propagation, and stale-while- revalidate covers the protocol model but does not deeply address the strategic decisions — TTL selection, cache invalidation, revalidation policies — that most teams actually need help with.


Scientific Grounding

| Concept | Primary Source | Where in the Book | |---|---|---| | TCP congestion control | Jacobson (1988, SIGCOMM) | Chapter 2, slow start + congestion avoidance | | TCP selective ACK | Jacobson & Braden (1988 RFC 2018) | Loss recovery discussion | | TLS 1.3 | RFC 8446 (Rescorla & Schiffman, 2018) | Chapter 2, 0-RTT and session resumption | | TLS record layer | Dierks & Allen (1999 RFC 2246) | TLS handshake diagram | | HTTP/2 framing | IETF, RFC 7540 (2015) | Chapter 3, multiplexing and HEADERS frames | | HTTP/2 HPACK header compression | Peon & Ruellan, RFC 7541 | Chapter 3, static and dynamic tables | | QUIC transport | IETF, RFC 9000 (Langley et al., 2021) | Chapter 4, all sections | | QPACK (HTTP/3 header compression) | IETF, RFC 9204 | Chapter 4,QUIC header section | | WebRTC data channels | IETF, RFC 7675 + W3C spec | Chapter 5, WebRTC internals | | Critical Rendering Path | Browser engine research (Blink/Gecko) | Chapter 6, reflow and repaint | | Wi-Fi CSMA/CA | IEEE 802.11 standard | Chapter 1, wireless behavior |


Historical Context

  • 2008: SPDY begins as a Google experiment. The web observes with skepticism.
  • 2012: SPDY v3 gains adoption. Google and Mozilla push for a standardized HTTP/2.
  • 2013: High Performance Browser Networking first edition ships, arguing that HTTP/2 + SPDY is the future, then HTTP/2 formalizes, then QUIC is publicly announced. Grigorik is writing about protocols that have not yet shipped.
  • 2015: HTTP/2 (RFC 7540) publishes. Browsers begin rolling it out. Chrome, Firefox, Safari, and Edge all support it within 12 months of publication.
  • 2018: Chrome starts shipping QUIC in production on Google services. QUIC IETF working group is active.
  • 2021: Second edition ships. QUIC is a first-class section. TLS 1.3 is standard. HTTP/3 is in development at IETF.
  • 2024: HTTP/3 (RFC 9114) publishes with official status. WebRTC data channels are production at scale. The second edition is now refreshed from a spec that did not exist when it was written.
  • 2026: HTTP/3 and QUIC replacement adoption is mature at CDN providers. The book's predictions about why HTTP/3 matters (head-of-line blocking, 0-RTT, web transport) have proven correct.

The two editions of HPBN are essentially snapshots of the same argument at two different moments: 2013 (early HTTP/2, QUIC is a research project) and 2021 (QUIC, HTTP/3 imminent, TLS 1.3 deployed). The argument — latency is the bottleneck, and the protocol stack has specific levers to pull — has not changed.


Comparison

| Book | Author | Focus | Compared to HPBN | |---|---|---|---| | High Performance Browser Networking (2nd) | Grigorik | Browser networking stack, HTTP/2, HTTP/3, QUIC | The only book covering this specific stack from a practitioner | | Computer Networking: A Top-Down Approach | Kurose & Ross | General computer networking textbook | Broader, deeper, less web-specific | | TCP/IP Illustrated, Vol. 1 | Kevin Fall | Packet-level TCP/IP reference | Deeper protocol internals; less applied to web | | Web Scalability for Startup Engineers | Ejsmont | Application and infrastructure scaling | Higher layer; fewer network internals | | Designing Data-Intensive Applications | Kleppmann | Distributed data principles | Highest level; minimal protocol detail | | High Performance MySQL | Schwartz et al. | Database operations and scaling | Database layer, not the web transport layer |


Final Assessment

| Dimension | Rating | Notes | |---|---|---| | Depth | 8/10 | Appropriate for a practitioner guide; does not replace a textbook | | Currency | 9/10 | Second edition (2021) covers QUIC and HTTP/3 post-IETF-spec | | Practical Utility | 9/10 | Every chapter ends with actionable takeaways | | Readability | 9/10 | Grigorik's prose is clear, direct, and occasionally funny | | Coverage of Wireless/Mobile | 9/10 | Exceptional: most web networking books elide this entirely | | Coverage of Rendering | 8/10 | Good; not as deep as browser-dedicated rendering books | | Measurement Practice | 8/10 | Good API coverage; could include more wireshark + DevTools workflows | | Lasting Value | 9/10 | Principles survive protocol version changes; both editions remain useful | | Overall | 9.5/10 | The definitive practitioner's guide to browser networking |


narration

Introduction

Welcome to BookAtlas. Today: High Performance Browser Networking: What Every Web Developer Needs to Know About Browser Networking. Second edition, 2021. Author: Ilya Grigorik. Roughly 380 pages.

This is a book about what no one sees: the network traffic that happens between the moment a user clicks a link and the moment something appears on screen. It is also a book about what engineers feel but cannot name: the milliseconds that add up to a page feeling slow, the waterfalls in DevTools, the why-is-this-fast-on-wired-but-not-on-latte-Wi-Fi question.

Grigorik is the right author for this material. He was a performance engineer who worked on HTTP/2 outreach at Google. He made the argument to the web's largest properties that HTTP/2 was worth adopting before it was standard. He was right.


Why This Book Exists

Host: Most engineers think of the network as something out there — a black box that either works or doesn't. We write code, we deploy, we hope.

Guest: That framing is the problem. The network is not a black box. It is a stack of protocols, each with invisible behaviors, each with specific costs. TCP has slow start. TLS has a handshake. HTTP/1.x has a six-connections-per-origin limit. DNS has a cold-start cost. The browser has a rendering pipeline that cannot start until it has assembled CSSOM and DOM. Every one of those is a millisecond you can eliminate if you know it exists.

Host: And most web developers don't know any of that?

Guest: They know some of it. They know "minimize HTTP requests." They know "serve over HTTPS." But they do not know why. The why matters because the specific lever — connection reuse, TLS session resumption, rendering-blocking CSS — is different in each case. Minimizing HTTP requests was the right advice for HTTP/1.x. It is mostly wrong for HTTP/2, where fewer, larger transfers over one connection is faster.


TCP: The Room Where It Happens

Host: Let's start with TCP. It is the foundation of the web. What does a web developer need to understand about it?

Guest: Three things, really. First, slow start. Every new TCP connection starts with a congestion window of 10 packets. That window doubles every round trip until it reaches some limit. The result: the first few RTTs on every connection are structurally slow. This is why HTTP/1.x's six parallel connections are a symptom of slow start — six connections means six slow starts happening in parallel. HTTP/2's one connection per origin shares one slow start across all streams.

Host: So connection reuse is not just a hygiene thing. It is a real performance lever.

Guest: Much more real than most developers assume. Second: Nagle's algorithm and delayed ACK. Nagle says "if you have small data, wait a bit before sending, in case there is more." Delayed ACK says "wait a bit before acknowledging, in case the application has data to piggyback." Together, on a request-response protocol like HTTP, they create a deadlock. The client sends a request, Nagle waits. The server ACKs, delayed ACK waits. Both are waiting for the other to move first. That is a 40ms cost per request on many systems, baked into the TCP stack.

Host: That is a hidden tax.

Guest: Every millisecond is a hidden tax until you measure it. And most developers never see it because it is inside the TCP stack, not in their application code.

Host: What about the third thing?

Guest: TCP Fast Open. It pushes application data into the initial SYN packet. The server can respond in the SYN-ACK. One round trip eliminated. It is not universally available — NATs and middleboxes break it — but in environments where it works, it is a genuine first-load win.


TLS: Security and Performance Are Not Opposites

Host: TLS used to be the reason people said "HTTPS is slow." Has that changed?

Guest: Completely. TLS 1.3 is a performance breakthrough. The old TLS 1.2 handshake required two round trips. TLS 1.3 does it in one. Session resumption is half a round trip. And with a session ticket from a previous visit, TLS 1.3 can send actual application data in the very first packet the client sends. That is zero round trips for the application data.

Host: That sounds like a lot.

Guest: Quantify it: on a 50ms RTT mobile link, full TLS 1.3 is 50ms instead of 100ms. That is a full page load saved before any bytes are requested. cryptographically, TLS 1.3 removed all the insecure and slow ciphers. RSA key transport is gone. All key exchange is ephemeral Diffie-Hellman. The same handshake that is faster is also more secure. This is one of those cases where optimization and correctness went in the same direction.


HTTP/1.x: The Waterfall Is Protocol Behavior, Not Bad Code

Host: HTTP/1.x is often blamed for slow sites. What actually goes wrong?

Guest: Everything in HTTP/1.x serializes. The browser limits connections to six per origin. Each request goes on its own connection and waits for the response before the next request on that connection pipeline. In DevTools, this looks like a staircase — a waterfall of many small round trips.

Host: People think that means their server is slow.

Guest: Often the server is fast. It is the protocol. The request reached the server in 20ms. The response returned in 5ms. But between them, the browser waited for the previous response, and the connection was idle because of the per-origin limit. That is not server latency; it is protocol latency.


HTTP/2: Multiplexing as the Answer

Host: HTTP/2 fixes this with multiplexing?

Guest: That is the headline, yes. One connection per origin, many concurrent streams. But the deeper fix is a change in the cost model:

Under HTTP/1.x, the cost of adding another asset is a full round trip on a connection that also has to do slow start. Under HTTP/2, the cost of adding another stream is a small framing overhead on a connection that is already mature and has a large congestion window.

flowchart LR
    A["HTTP/1.x: 6 parallel connections"] -->|"Each starts slow start"| B["6 waterfalls<br/>serial on each connection"]
    C["HTTP/2: 1 connection, many streams"] -->|"Shares one slow start"| D["One ramp-up<br/>many concurrent transfers"]

Host: And compression?

Guest: HPACK. Header compression. HTTP requests are mostly the same headers with small variations. HPACK builds a static and dynamic table so that repeated headers — Host, User-Agent, Accept — are sent as small index references instead of full text. This matters on high- latency, low-bandwidth links where every byte counts.

Server push is the other headline feature. The server can, in the initial response, begin sending assets it knows the client will need — CSS, JavaScript that the HTML references. Push eliminates the request round trip entirely for those assets. It requires careful Cache-Digest and management to avoid sending assets the client already has, but when it works, it is genuine page-load acceleration.


HTTP/3 and QUIC: Fixing the Final Layer

Host: If HTTP/2 solved head-of-line blocking, why do we need HTTP/3?

Guest: HTTP/2 solved head-of-line blocking at the application layer. But TCP still has it at the transport layer. TCP is a byte stream: one lost packet means all streams waiting on that connection wait for retransmission. On a lossy mobile link, this is a real, measurable drag.

Host: So QUIC fixes that at the transport layer.

Guest: Exactly. QUIC is TCP reimplemented in user space over UDP. It solves congestion control, ordering, and reliability — but it does it per stream, not per connection. One lost packet stalls one HTTP/3 stream. All other streams continue. Combined with TLS 1.3 built in, QUIC also saves round trips on the security handshake.

flowchart TB
    subgraph TCP["TCP: One Connection"]
        S1["Stream 1"] --> TC
        S2["Stream 2"] --> TC
        S3["Stream 3"] --> TC
        TC["TCP Layer<br/>(one lost packet stalls all)"]
    end
    subgraph QUIC["QUIC: One Connection, Many Loss Events"]
        Q1["Stream 1"] --> QR1["QUIC Stream 1<br/>(independent recovery)"]
        Q2["Stream 2"] --> QR2["QUIC Stream 2<br/>(independent recovery)"]
        Q3["Stream 3"] --> QR3["QUIC Stream 3<br/>(independent recovery)"]
    end

The book explains that QUIC's other feature — connection migration — means your phone does not lose its state when switching from Wi-Fi to cellular. TCP connections are identified by a 4-tuple of source IP, source port, dest IP, dest port. Change IP and the connection breaks. QUIC uses a connection ID in the encrypted payload — change the IP and the connection follows. This is why QUIC matters more on mobile than on desktop.


WebRTC: Beyond Browsers to Peer-to-Peer

Host: The book covers WebRTC. What does a web performance book need to say about it?

Guest: WebRTC is in the book because it is a browser networking primitive that sits outside the usual request-response model. The browser can open a peer-to-peer data channel — no server in between carrying the traffic — using ICE, STUN, and TURN to traverse NATs.

STUN asks a public server: "what is my public IP and port?" TURN relays the traffic when STUN alone fails.

Host: When does TURN fire?

Guest: Symmetric NATs, mobile carrier-grade NATs, enterprises behind firewalls that block UDP. TURN is the fallback. The data channel still works, but latency goes through TURN server, and bandwidth costs you per gigabyte.


The Rendering Pipeline: The Invisible Final Mile

Host: The book ends on rendering. Why does a networking book care about reflow and repaint?

Guest: Because arriving bytes hit a rendering pipeline before the user sees anything. The fastest server in the world cannot deliver a perceived speed win if the browser is sitting in layout thrashing.

flowchart TB
    Bytes["Arriving Bytes"] --> Parse["Parse HTML<br/>(tokenizer)"]
    Parse --> DOM["Build DOM"]
    Bytes --> CSSParse["Parse CSS"]
    CSSParse --> CSSOM["Build CSSOM"]
    DOM --> Render["Render Tree"]
    CSSOM --> Render
    Render --> Layout["Layout (Reflow)<br/>compute geometry"]
    Layout --> Paint["Paint<br/>draw pixels"]
    Paint --> Composite["Composite<br/>GPU layers"]

Render-blocking CSS means: link rel="stylesheet" in the head. The browser sees the CSS, builds CSSOM, builds the render tree, and only then starts layout and paint. If your CSS is mid-page, nothing paints.

The book explains render-blocking CSS: inlining critical CSS above the fold, async-loading non-critical stylesheets with media="print", and preload for fonts. These are network-side optimizations that live in the HTML — the first thing the network delivers.

JavaScript that writes to the DOM forces reflow. Animating a property that affects layout forces a full reflow every frame. The render pipeline is where "the network is fast but the page feels janky" hides.


Reporting APIs: Measuring What You Cannot See

Host: You cannot optimize what you cannot measure. The book has a real emphasis on this.

Guest: The Navigation Timing API gives you a timing profile of a page load from the perspective of the browser: DNS time, TCP handshake time, TLS time, Time to First Byte, DOM processing, load event. It is the only way to correlate network behavior with user-perceived speed at scale.

const [nav] = performance.getEntriesByType('navigation');
console.log({
  dns: nav.domainLookupEnd - nav.domainLookupStart,
  tcp: nav.connectEnd - nav.connectStart,
  tls: nav.requestStart - nav.connectStart,
  ttfb: nav.responseStart - nav.requestStart,
  dom: nav.domContentLoadedEventEnd - nav.responseEnd,
  load: nav.loadEventEnd - nav.responseEnd,
});

The Resource Timing API does the same for individual fetched assets. Together, these APIs are the feedback loop: you change a setting, you deploy, and you see in real user data whether the waterf fall got shorter.

Host: And the setup cost of these APIs is zero — it is built into every modern browser.

Guest: Exactly. The book's position: if you are not collecting performance.getEntriesByType() data from your real users, you are optimizing blind.


The Verdict

Guest: High Performance Browser Networking is a book written by an engineer who was in the room where the standards were being written and who has run the servers under real traffic. It is not a textbook and it is not a journalism project. It is a field manual.

It covers the protocol stack in the order you encounter it — TCP, TLS, DNS, HTTP/1.x, HTTP/2, HTTP/3, WebRTC — and ends where performance is measured: the rendering pipeline and the browser timing APIs.

Host: And the argument?

Guest: The argument is consistent and quantifiable: latency is the bottleneck, not bandwidth. Every layer has a specific cause and a specific fix. TCP slow start. Nagle's algorithm. TLS handshakes. DNS cold-start. Render-blocking CSS. None of these require a faster server. They require understanding.

Host: Final rating?

Guest: 9.5 out of 10. The notes that follow each chapter — the specific config flags, the sequence diagrams, the TCP constant values — are worth the cover price on their own. If you write web code for a living and have not read this, read it. If you have read it and it has been a few years, the second edition's QUIC section is enough reason to revisit.

This has been a BookAtlas narration of High Performance Browser Networking by Ilya Grigorik. Thanks for listening.