Web Performance · Part 19 — Network Protocol & Transport Performance
Tầng truyền tải ảnh hưởng tốc độ ra sao: HTTP/1.1 vs HTTP/2 vs HTTP/3 (QUIC), head-of-line blocking, nén Brotli/Zstd, TLS 1.3 & 0-RTT, CDN/edge, và cache-control nâng cao.
Phần 11 bàn caching cơ bản. Phần này đi xuống tầng truyền tải — giao thức HTTP và TCP/QUIC bên dưới mọi request. Đây là phần nhiều frontend dev coi là “hộp đen của ops”, nhưng hiểu nó giải thích vì sao chiến lược bundle thời HTTP/1.1 cần đổi, HTTP/3 giúp gì khi mất gói, và làm sao cấu hình cache cho đúng.
Mỗi byte phải đi qua: DNS → kết nối (TCP/QUIC + TLS) → request → response. Tối ưu tầng này rút ngắn TTFB và mở khóa song song — nền cho mọi tài nguyên phía trên.
1. HTTP/1.1 → HTTP/2: multiplexing
Browser hiện đại thường không dùng HTTP/1.1 pipelining, nên mỗi kết nối chỉ có một request đang phản hồi tại một thời điểm và mở một nhóm kết nối song song (thường khoảng 6, tùy browser/origin). Nhiều file → xếp hàng. Đó là lý do thời HTTP/1.1 ta gộp file, dùng sprite, domain sharding.
HTTP/1.1: 6 kết nối, mỗi cái 1 request một lúc → file thứ 7 phải chờ
HTTP/2: thường 1 kết nối/origin, MULTIPLEXING nhiều stream song song
HTTP/2 ghép nhiều request/response trên một kết nối qua các stream độc lập. Hệ quả thực tế:
- Không còn cần bundle khổng lồ, sprite hay domain sharding chỉ để né giới hạn kết nối HTTP/1.1.
- Có thể chia bundle theo route/feature để caching tốt hơn, nhưng quá nhiều chunk nhỏ vẫn có overhead header, scheduling, nén và parse. Đo để tìm granularity phù hợp.
2. Head-of-line blocking & HTTP/3 (QUIC)
HTTP/2 multiplexing ở tầng HTTP, nhưng vẫn chạy trên TCP. TCP đảm bảo thứ tự byte: nếu một gói tin mất, mọi stream trên kết nối đó phải chờ truyền lại — TCP head-of-line blocking. Trên mạng kém (mobile, mất gói cao), điều này giết hiệu năng dù đã multiplexing.
HTTP/2 trên TCP: gói của stream A mất → stream B, C cũng kẹt chờ (HOL blocking)
HTTP/3 trên QUIC (UDP): mỗi stream độc lập ở tầng truyền tải
→ gói stream A mất CHỈ chặn A; B, C chạy tiếp ✅
HTTP/3 chạy trên QUIC (trên UDP), loại bỏ TCP HOL giữa các QUIC stream: mất dữ liệu của stream A không buộc B/C chờ retransmit của A. Nó không xóa mọi tác động của mất gói — congestion control vẫn có thể giảm tốc cả connection, và chính stream A vẫn chờ dữ liệu thiếu. QUIC tích hợp TLS và hỗ trợ connection migration, thường hữu ích trên mạng latency/mất gói cao; mức cải thiện phải đo theo người dùng thật.
3. TLS 1.3 & 0-RTT — bắt tay nhanh hơn
Thiết lập kết nối an toàn tốn round-trip. TLS 1.3 giảm bắt tay xuống 1-RTT, và 0-RTT cho phép gửi dữ liệu ngay khi kết nối lại với server đã biết.
TLS 1.2: 2-RTT bắt tay → chậm hơn
TLS 1.3: 1-RTT → nhanh hơn
TLS 1.3 + 0-RTT (resumption): 0-RTT cho lần kết nối lại → gửi request ngay
QUIC: gộp transport + TLS → ít round-trip hơn nữa
Cảnh báo bảo mật 0-RTT: early data có thể bị replay. Chỉ chấp nhận operation được thiết kế replay-safe và có policy/anti-replay phía server; đừng suy rằng mọi
GETđều an toàn chỉ vì method được xem là idempotent (một endpoint GET viết sai vẫn có thể tạo side effect).
4. Nén — Brotli & Zstd
Nén giảm byte truyền. Với text (HTML/CSS/JS/JSON), Brotli thường tạo response nhỏ hơn gzip; Zstandard (zstd) có thể cân bằng tốt giữa tốc độ và tỉ lệ. Kết quả phụ thuộc corpus, quality level và CPU — không có một phần trăm đúng cho mọi site.
Hiệu quả nén text (xấp xỉ):
gzip → baseline
Brotli → thường nhỏ hơn gzip cho asset text tĩnh
Zstd → nén/giải nén nhanh ở nhiều mức, support client còn cần kiểm tra
Nguyên tắc:
- pre-compress asset tĩnh lúc build; chọn quality bằng benchmark, không mặc định mức tối đa
- nén động cho response sinh-tại-chỗ ở mức vừa (cân CPU)
- ĐỪNG nén lại thứ đã nén: ảnh (jpg/png/webp/avif), woff2, video, zip
- Content-Encoding đúng + Vary: Accept-Encoding
Đa số ảnh và woff2 đã nén sẵn — nén lại tốn CPU mà không giảm byte.
Server phải negotiate qua Accept-Encoding và luôn có fallback br/gzip cho client hoặc intermediary chưa hỗ trợ zstd; gửi Vary: Accept-Encoding để cache không trộn các representation.
5. CDN & edge — gần người dùng hơn
CDN đặt nội dung ở edge gần người dùng, cắt latency (khoảng cách vật lý = thời gian). Vai trò hiệu năng:
- phục vụ asset tĩnh từ edge gần nhất → TTFB & LCP thấp
- TLS termination ở edge → bắt tay nhanh hơn
- HTTP/3 + 0-RTT ở edge
- edge cache cho cả HTML động (với cache key/purge đúng)
- edge compute (Workers/Functions) → render/cá nhân hóa gần người dùng
Edge rendering có thể giảm network latency, nhưng không tự động hạ TTFB nếu compute cold-start hoặc vẫn phải gọi database ở một region xa. Đặt cache/compute gần người dùng và gần dependency phù hợp, rồi kiểm tra bằng Server-Timing và field TTFB.
6. Cache-Control nâng cao
Header cache quyết định trình duyệt/CDN giữ và tái dùng response thế nào. Vài pattern senior:
Các dòng # dưới đây là chú thích cho từng policy, không phải header gửi trên wire:
# Asset có hash trong tên (app.a1b2c3.js) → bất biến, cache 1 năm
Cache-Control: public, max-age=31536000, immutable
# HTML → luôn revalidate (nội dung có thể đổi)
Cache-Control: no-cache # = phải kiểm tra với server (ETag) trước khi dùng
# stale-while-revalidate: phục vụ bản cũ NGAY, làm tươi ở nền
Cache-Control: public, max-age=60, stale-while-revalidate=600
Các chỉ thị then chốt:
immutable → đừng revalidate trong max-age (asset có hash)
no-cache ≠ no-store → no-cache: cache nhưng phải revalidate;
no-store: không lưu gì cả
stale-while-revalidate → trả stale ngay + cập nhật nền (UX mượt)
s-maxage / private → kiểm soát riêng cho CDN vs trình duyệt
Baseline an toàn phổ biến: HTML
no-cache(được lưu nhưng phải revalidate) + asset hashimmutable1 năm. Đây không phải policy duy nhất: HTML công khai có thể dùngs-maxage/stale-while-revalidateở CDN, còn response cá nhân hóa cầnprivatehoặcno-storecùng cache key đúng. Luôn thiết kế purge/invalidation trước khi tăng TTL.
7. Tóm tắt
- HTTP/2 multiplexing bỏ lý do gộp file chỉ để né connection limit, nhưng quá nhiều chunk nhỏ vẫn có overhead.
- HTTP/3 (QUIC trên UDP) loại TCP HOL giữa stream; mất gói và congestion vẫn tồn tại, nên lợi ích tùy mạng.
- TLS 1.3 bắt tay 1-RTT, 0-RTT cho kết nối lại chỉ với operation replay-safe và server policy đúng.
- Nén Brotli/Zstd cho text với content negotiation + fallback; benchmark quality và đừng nén lại ảnh/woff2/video.
- CDN/edge cắt latency bằng cách phục vụ gần người dùng (asset tĩnh, TLS, HTTP/3, edge render).
- Cache-Control: asset hash
immutable; HTML chọnno-cache, CDN TTL hayprivate/no-storetheo loại dữ liệu; phân biệtno-cachevsno-store.
Phần tiếp theo: Third-party script performance — chế ngự analytics/ads/embed/tag manager bằng facade pattern, Partytown (đẩy sang worker), lazy iframe và đặt budget cho bên thứ ba.