Networking
HTTP/2
Major revision improving web performance
Intermediate
http protocol performance networking
Definition
HTTP/2 is a major revision of the HTTP protocol that brings significant performance improvements through multiplexing, header compression, and server push. It maintains backward compatibility with HTTP/1.1 semantics while solving head-of-line blocking and reducing latency.
Key Features
1. Multiplexing
HTTP/1.1: HTTP/2:
Connection 1: CSS ────── Single Connection:
Connection 2: JS ──────── Stream 1: CSS ──┐
Connection 3: Image ──── Stream 2: JS ───┼── Interleaved
Connection 4: Image ──── Stream 3: Image─┘
Connection 5: Image ──── Stream 4: Image
6 connections 1 connection
Head-of-line blocking No blocking
Multiple requests share a single TCP connection, interleaved frame by frame.
2. Header Compression (HPACK)
HTTP/1.1 Request #1: HTTP/2 Request #1:
GET /page1 HTTP/1.1 :method: GET
Host: example.com :path: /page1
Accept: text/html :authority: example.com
Accept-Language: en-US :scheme: https
Accept-Encoding: gzip
User-Agent: Mozilla/5.0...
Cookie: session=abc123...
(~400 bytes)
HTTP/1.1 Request #2: HTTP/2 Request #2:
GET /page2 HTTP/1.1 :path: /page2
Host: example.com (10 bytes - referenced from table)
Accept: text/html
Accept-Language: en-US
Accept-Encoding: gzip
User-Agent: Mozilla/5.0...
Cookie: session=abc123...
(~400 bytes again)
HPACK compresses headers and maintains a lookup table to avoid sending duplicate values.
3. Binary Framing
HTTP/1.1 (Text): HTTP/2 (Binary):
GET / HTTP/1.1 ┌─────────────────┐
Host: site.com │ Length (24 bits)│
│ Type (8 bits) │
│ Flags (8 bits) │
│ Reserved (1 bit)│
│ Stream ID (31) │
│ Payload │
└─────────────────┘
More efficient parsing
No need to parse text
4. Stream Prioritization
// Browser can indicate priority
Stream 1: HTML (Priority: 256) ──────┐
Stream 2: CSS (Priority: 220) ───────┤
Stream 3: JS (Priority: 220) ────────┤ Critical resources
Stream 4: Image (Priority: 110) ─────┤
Stream 5: Analytics (Priority: 0) ───┘ Low priority
Server sends critical resources first
5. Server Push (Deprecated)
// Server can preemptively push resources
// Client requests: index.html
// Server pushes: styles.css, app.js
// Note: Server Push is deprecated in practice
// due to cache issues and complexity
Performance Impact
Connection Reduction
// HTTP/1.1: Domain sharding needed
<link rel="stylesheet" href="https://cdn1.example.com/style.css">
<link rel="stylesheet" href="https://cdn2.example.com/theme.css">
<script src="https://cdn3.example.com/app.js"></script>
// 3 connections, 3 DNS lookups, 3 TLS handshakes
// HTTP/2: Single connection sufficient
<link rel="stylesheet" href="https://example.com/style.css">
<link rel="stylesheet" href="https://example.com/theme.css">
<script src="https://example.com/app.js"></script>
// 1 connection, 1 DNS lookup, 1 TLS handshake
Loading Strategies Change
// HTTP/1.1: Concatenation was critical
// bundle.js (all JS combined)
// styles.css (all CSS combined)
// HTTP/2: Granular loading is fine
// Component-based loading
// Smaller, cacheable chunks
Enabling HTTP/2
Nginx
server {
listen 443 ssl http2;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
# HTTP/2 is enabled!
}
Node.js
const http2 = require('http2');
const fs = require('fs');
const server = http2.createSecureServer({
key: fs.readFileSync('server.key'),
cert: fs.readFileSync('server.cert')
});
server.on('stream', (stream, headers) => {
stream.respond({
'content-type': 'text/html',
':status': 200
});
stream.end('<h1>Hello HTTP/2</h1>');
});
server.listen(8443);
CDN
// Most CDNs enable HTTP/2 automatically
// Cloudflare, Fastly, CloudFront, etc.
Debugging HTTP/2
Browser DevTools
// Chrome DevTools:
// 1. Network tab
// 2. Right-click columns > Enable "Protocol"
// 3. Look for "h2" in Protocol column
// Or check response headers
// Look for: < HTTP/2 200
Command Line
# Check HTTP/2 support
curl -I --http2 https://example.com
# Force HTTP/2
curl --http2-prior-knowledge https://example.com
# Detailed protocol info
curl -v --http2 https://example.com 2>&1 | grep -E "(HTTP/2|TLS|ALPN)"
Best Practices
HTTPS Required
// HTTP/2 requires TLS (in practice)
// Browsers only support HTTP/2 over HTTPS
// Always redirect HTTP to HTTPS
if (location.protocol !== 'https:') {
location.replace('https://' + location.href);
}
Optimize for HTTP/2
// 1. Stop concatenating everything
// ❌ Old approach for HTTP/1.1
// app.bundle.js (500KB)
// ✅ HTTP/2 approach
// vendor.js (200KB - cached long-term)
// app.js (100KB - changes often)
// components/*.js (lazy loaded)
// 2. Stop domain sharding
// ❌ Don't do this
<img src="https://cdn1.site.com/a.jpg">
<img src="https://cdn2.site.com/b.jpg">
// ✅ Single domain is fine
<img src="https://cdn.site.com/a.jpg">
<img src="https://cdn.site.com/b.jpg">
// 3. Keep resources granular
// Code splitting works great with HTTP/2
HTTP/2 Limitations
Head-of-Line Blocking (TCP Level)
HTTP/2 Multiplexing:
Stream 1: Packet 1 ────┐
Stream 2: Packet 1 ────┤ All in one TCP connection
Stream 3: Packet 1 ────┘
If Packet 1 of Stream 1 is lost:
- TCP requires retransmission
- All streams blocked until retransmission
This is solved by HTTP/3 (QUIC)
Migration Checklist
□ Enable HTTPS (required)
□ Update server to support HTTP/2
□ Test all resources load correctly
□ Remove domain sharding
□ Consider granular code splitting
□ Monitor performance metrics
□ Check third-party resources support HTTP/2
Key Takeaway
HTTP/2 improves performance through multiplexing, header compression, and binary framing. Use HTTPS, stop domain sharding, and embrace granular loading. It’s widely supported and provides automatic performance gains for most sites.