Many optimization rules still circulating today were born in the days of HTTP/1.1: merging all files into one, creating image sprites, spreading resources across several subdomains. With HTTP/2 and HTTP/3 some of these practices have become pointless, others outright harmful. It is worth understanding what changed at the protocol level in order to decide knowingly.
The problem with HTTP/1.1
With HTTP/1.1 each TCP connection can handle only one request at a time: you send it, wait for the complete response, then send the next. To avoid queuing everything, browsers open up to six parallel connections per domain. A page with eighty resources on the same domain therefore downloads them in groups of six, and each extra connection costs its own handshake.
Hence the classic optimizations:
- concatenation of CSS and JavaScript into a few large files;
- image sprites, that is many icons in a single image;
- domain sharding, spreading resources across different subdomains to get more parallel connections;
- aggressive inlining of small resources directly into the HTML.
What HTTP/2 brings
HTTP/2 introduces multiplexing: many independent streams travel in parallel over a single connection, split into interleaved frames. The browser can request a hundred resources together without opening a hundred connections. In addition, headers are compressed with HPACK, which avoids repeating the same block of cookies and headers on every request.
The practical consequences:
- domain sharding becomes counterproductive: each extra domain needs a separate connection and TLS negotiation, and prevents the browser from managing all priorities on a single connection;
- extreme concatenation loses its point: a single huge bundle invalidates the whole cache on every small change. Files of reasonable size, split by feature or page, which can be cached independently, are better;
- sprites are no longer needed to reduce requests; for icons it is often more practical to use individual SVGs or a symbol set.
Be careful not to overdo it in the other direction, though. Hundreds of tiny JavaScript modules loaded separately have a cost, both from the overhead of each request and from compression being less effective on very small files. The middle way, with a few dozen well-split files, works better.
The limit of HTTP/2 over TCP
HTTP/2 solves blocking at the application level, but a problem remains at the transport level: TCP guarantees that bytes arrive in order. If a packet is lost, all streams on the connection stop until it is retransmitted, even unrelated ones. This is called TCP head-of-line blocking and it is especially noticeable on mobile networks with packet loss.
What HTTP/3 brings
HTTP/3 replaces TCP with QUIC, a transport protocol built on top of UDP. The main differences:
| Aspect | HTTP/2 over TCP | HTTP/3 over QUIC |
|---|---|---|
| Losing a packet | blocks all streams | blocks only the affected stream |
| Connection start | TCP handshake, then TLS | transport and encryption together |
| Reconnection | new handshake | faster resumption, even with early data |
| Network change | the connection drops | the connection can continue |
The last item helps people browsing on the move: when switching from Wi-Fi to cellular, QUIC uses connection identifiers that do not depend on the IP address, so the session can continue.
The browser discovers that a server supports HTTP/3 through the Alt-Svc header or an HTTPS-type DNS record; the first visit may therefore still use HTTP/2 and later ones HTTP/3. If UDP is blocked by a corporate firewall, the browser automatically falls back to HTTP/2.
What still matters
The protocol improves transport, not content. These remain valid:
- reducing the overall weight of JavaScript, images and fonts;
- avoiding dependency chains, because each step is still a round trip;
- limiting the number of third-party domains, each with its own connection;
- assigning correct priorities to critical resources, for example with
fetchpriority.
How to check the protocol
In DevTools, in the Network panel, the «Protocol» column shows h2 for HTTP/2 and h3 for HTTP/3. If many http/1.1 requests still appear, check which server or third-party domain is serving them. Often the main site is up to date, while an old image CDN or an external service still uses the earlier protocol.
In short
- HTTP/2 allows many parallel requests over a single connection thanks to multiplexing.
- Domain sharding and sprites are outdated; extreme concatenation hurts caching.
- HTTP/3 over QUIC avoids stalling every stream when a packet is lost and survives network changes.
- The protocol does not replace reducing weight and dependency chains.
- Check the Protocol column in DevTools to find out who still uses HTTP/1.1.