Kiến thức công nghệ · 02/10/2026

HTTP 103 Early Hints: Tăng tốc tải trang mà không preload quá tay

Trong lúc backend còn truy vấn database hoặc render HTML, trình duyệt thường chỉ biết chờ. HTTP 103 Early Hints tận dụng khoảng “server think time” đó: server, reverse proxy hoặc CDN gửi trước một response thông tin chứa các Link hint để browser có thể kết nối sớm hoặc tải tài nguyên quan trọng, rồi response cuối như 200, 302 hay 404 mới đến sau.

HTTP 103 Early Hints: Tăng tốc tải trang mà không preload quá tay

Trong lúc backend còn truy vấn database hoặc render HTML, trình duyệt thường chỉ biết chờ. HTTP 103 Early Hints tận dụng khoảng “server think time” đó: server, reverse proxy hoặc CDN gửi trước một response thông tin chứa các Link hint để browser có thể kết nối sớm hoặc tải tài nguyên quan trọng, rồi response cuối như 200, 302 hay 404 mới đến sau.

Early Hints không tự làm mọi trang nhanh hơn. Nếu chọn sai tài nguyên, browser có thể tải dữ liệu không dùng, cạnh tranh băng thông với ảnh LCP hoặc tải lại do metadata preload không khớp. Giá trị thật đến từ hint ít, ổn định, cacheable và được kiểm chứng bằng dữ liệu người dùng.

1. Response 103 nằm ở đâu trong một request?

GET /products/42 HTTP/2
Host: example.com

HTTP/2 103 Early Hints
Link: </assets/app.css>; rel=preload; as=style
Link: <https://static.example-cdn.com>; rel=preconnect

HTTP/2 200 OK
Content-Type: text/html; charset=utf-8
Link: </assets/app.css>; rel=preload; as=style

<!doctype html>
...

Theo RFC 8297, 103 là informational response: client có thể đánh giá các header để tối ưu hiệu năng trong khi chờ response cuối. Header trong 103 chỉ là gợi ý, không thay thế header của response cuối và không được làm thay đổi cách response cuối được xử lý ngoài mục đích tối ưu.

Điều này khác redirect. Browser không chuyển trang khi gặp 103 và request cũng chưa hoàn tất. Nó tiếp tục chờ status cuối. Một request có thể nhận informational response trước final response, nhưng ứng dụng không được coi 103 là bằng chứng rằng trang chắc chắn sẽ trả 200.

2. Vì sao gửi Link trong HTML đôi khi quá muộn?

Thông thường browser chỉ phát hiện CSS, font và JavaScript sau khi:

  1. Hoàn tất kết nối và gửi request document.
  2. Chờ backend tạo response.
  3. Nhận các byte HTML đầu tiên.
  4. Parse đến thẻ <link> hoặc <script>.

Nếu backend mất 400 ms để render, tài nguyên render-blocking bị phát hiện muộn khoảng thời gian đó. 103 cho phép gửi hint ngay khi route được nhận diện, trước khi truy vấn chậm hoàn tất. Lợi ích tiềm năng lớn hơn khi TTFB phía backend đáng kể và asset nằm trên kết nối chưa mở.

Với trang tĩnh được CDN trả gần như tức thời, khoảng để “đi sớm” rất nhỏ. Thêm Early Hints có thể không tạo cải thiện đo được.

3. Preconnect và preload khác nhau

HintBrowser chuẩn bị gì?Rủi ro chính
rel=preconnectDNS, TCP và TLS tới một originMở kết nối không dùng, tốn socket/năng lượng
rel=preloadTải một resource cụ thể sớmCạnh tranh băng thông hoặc tải đôi nếu metadata sai

preconnect phù hợp khi biết chắc trang sẽ dùng một origin bên ngoài nhưng asset chính xác còn phụ thuộc response. preload mạnh hơn và chỉ nên dùng cho resource critical, ổn định: CSS chặn render, font quan trọng hoặc script thiết yếu.

Mức hỗ trợ khác nhau giữa browser và loại hint. Tài liệu Early Hints của Chrome for Developers lưu ý rằng hỗ trợ preconnect và preload không hoàn toàn đồng nhất. Hãy thiết kế final HTML vẫn đúng khi client bỏ qua 103.

4. Metadata preload phải khớp request thật

Link: </assets/site.css>; rel=preload; as=style
Link: </assets/app.js>; rel=preload; as=script
Link: </assets/brand.woff2>; rel=preload; as=font; type="font/woff2"; crossorigin

Thuộc tính as quyết định destination, priority và CSP context. Font cross-origin thường cần crossorigin phù hợp. Nếu Early Hint tải font theo một credentials mode nhưng CSS yêu cầu mode khác, browser có thể không tái sử dụng response và gửi request lần hai.

Để tránh double fetch, đảm bảo URL chuẩn hóa, query version, as, type, crossorigin và cache policy khớp với cách final document sử dụng asset. Redirect asset cũng làm đường tải khó đoán hơn; ưu tiên URL cuối ổn định.

5. Chọn candidate bằng critical path, không bằng kích thước danh sách

Mỗi hint là một quyết định sử dụng network sớm. Một shortlist tốt thường gồm:

  • Stylesheet render-blocking dùng trên gần như mọi biến thể của route.
  • Font thực sự xuất hiện above the fold và có chiến lược font-display phù hợp.
  • Script thiết yếu cho render/hydration, không phải analytics hoặc widget dưới fold.
  • Preconnect tới origin chắc chắn phục vụ resource critical.

Không preload toàn bộ bundle, mọi font weight, carousel ảnh hoặc asset “có thể dùng”. Preload sai có thể chiếm bandwidth của document và ảnh LCP. Với mobile connection chậm, chi phí prediction sai lớn hơn desktop mạng nhanh.

Một hint đúng và ổn định thường giá trị hơn mười hint dự đoán.

6. Route động và personalization cần strategy riêng

CDN có thể tạo Early Hints từ Link header đã quan sát hoặc cấu hình theo route. Nhưng một URL động có thể trả nhiều template:

  • User chưa đăng nhập bị redirect tới login.
  • Experiment A/B dùng bundle hoặc CSS khác.
  • Trang sản phẩm lỗi 404 hoặc hết quyền truy cập.
  • Locale/tenant chọn theme khác nhau.

Nếu hint được gửi trước khi biết biến thể, browser có thể tải asset sai. Hãy dùng candidate chung cho mọi biến thể hoặc key cấu hình theo route/locale/tenant đáng tin cậy. Không dùng cookie chứa dữ liệu nhạy cảm để tạo URL hint có thể bị log/cached ngoài ý muốn.

Với response cuối chuyển hướng cross-origin, browser có thể bỏ resource hoặc connection tạo từ Early Hints. Đây là lý do các route redirect thường xuyên không phải điểm bắt đầu tốt.

7. Ví dụ ở Node.js và nguyên tắc ở reverse proxy

import http from 'node:http';

http.createServer(async (request, response) => {
  response.writeEarlyHints({
    link: [
      '</assets/app.css>; rel=preload; as=style',
      '<https://static.example-cdn.com>; rel=preconnect'
    ]
  });

  const html = await renderPage(request.url);
  response.writeHead(200, {
    'content-type': 'text/html; charset=utf-8'
  });
  response.end(html);
}).listen(8080);

Ví dụ minh họa API writeEarlyHints(); production phải xử lý lỗi render, timeout và final status. Nếu framework, proxy hoặc CDN hỗ trợ 103, thường nên phát hint ở lớp biết route sớm nhất nhưng vẫn hiểu asset manifest.

Kiểm tra toàn chuỗi. Origin có thể gửi 103 nhưng load balancer nuốt informational response; CDN có thể tự tạo 103 ngay cả khi origin không gửi; observability có thể chỉ ghi final status. Cấu hình ở một lớp không chứng minh client đã nhận hint.

8. Cacheability quyết định khả năng tái sử dụng

Resource được preload sớm thường đi qua HTTP cache để final page sử dụng lại. Nếu asset không cacheable hoặc metadata không khớp, request thật có thể tải lại. Candidate tốt nên có:

  • URL fingerprint theo nội dung, chẳng hạn app.7f3a.css.
  • Cache-Control phù hợp cho asset bất biến.
  • CORS header đúng nếu resource cross-origin cần CORS.
  • Không phụ thuộc cookie nếu có thể.
  • Content type chính xác và không redirect không cần thiết.

Đừng Early Hint API response cá nhân, tokenized URL hoặc tài nguyên mà final page có thể không dùng. 103 là speculation; speculative fetch vẫn tiêu tốn tài nguyên và có thể tạo dấu vết truy cập ở origin bên thứ ba.

9. Bảo mật và tính đúng đắn

Chỉ đưa vào Early Hints những header an toàn để client xử lý trước final response. RFC cảnh báo rằng hint có thể được xử lý trước khi request hoàn tất; việc lặp lại dữ liệu nhạy cảm hoặc policy chưa chắc chắn tạo rủi ro.

  • Không gửi Set-Cookie, auth data hoặc metadata riêng tư trong 103.
  • Không để URL preload tiết lộ trạng thái tài khoản hoặc nội dung người dùng.
  • Giữ response cuối là nguồn authoritative cho header semantics.
  • Kiểm tra CSP/CORS và integrity flow như request thông thường.
  • Giới hạn hint ở HTTPS tin cậy và HTTP/2 hoặc HTTP/3 theo khả năng hạ tầng/client.

Older client, bot hoặc proxy có thể xử lý informational response không tốt. Một chiến lược tương thích là chỉ bật cho navigation hiện đại qua HTTP/2+ và rollout theo traffic thực, nhưng không giả định một user-agent string là bằng chứng tuyệt đối.

10. Cách kiểm tra 103 có thật sự đến browser

curl -sS -D - --http2 https://example.com/products/42 -o /dev/null

Output cần cho thấy 103 trước final response. Sau đó dùng DevTools Network với certificate tin cậy; kiểm tra document có Early Hints header và resource có initiator/cache behavior phù hợp. Tắt cache trong DevTools có thể làm sai bài test vì cơ chế tái sử dụng preload dựa vào cache.

Hậu kiểm nhiều lớp:

  1. Origin hoặc CDN phát đúng 103 và đúng Link.
  2. Proxy không strip informational response.
  3. Browser thực sự bắt đầu request asset trước final response.
  4. Final HTML tái sử dụng asset, không tải đôi.
  5. Response lỗi, redirect và variant không preload sai.

11. Đo hiệu quả bằng RUM và A/B test

Đừng kết luận từ waterfall của một laptop. Chạy experiment có control và treatment, phân đoạn theo device, network, geography, cache state và route. Metric nên gồm:

  • LCP và FCP ở percentiles, không chỉ trung bình.
  • Thời điểm request critical CSS/font/script bắt đầu.
  • Tỷ lệ double fetch và byte tải không được sử dụng.
  • Final response time để biết khoảng think time có đủ lớn.
  • Error, redirect và cache-hit rate.

103 là byte đầu của informational response nên một số cách đo TTFB lịch sử có thể gây nhầm lẫn. Hãy phân biệt thời điểm nhận Early Hints với thời điểm final response header bắt đầu, và đặt mục tiêu vào trải nghiệm render thay vì cố làm một con số TTFB đẹp.

12. Checklist rollout production

  • Route có server think time đủ lớn và asset critical dự đoán ổn định.
  • Chỉ hint một tập nhỏ CSS/font/script hoặc origin thật sự quan trọng.
  • as, type, crossorigin, URL và credentials mode khớp final request.
  • Asset cacheable, versioned và không mang dữ liệu cá nhân.
  • Final page vẫn đúng nếu client bỏ qua toàn bộ 103.
  • Đã kiểm tra origin, proxy/CDN, HTTP/2/3, browser và redirect/error path.
  • Không có double fetch hoặc bandwidth contention đáng kể.
  • RUM/A/B test chứng minh LCP/FCP cải thiện ở nhóm người dùng mục tiêu.
  • Có kill switch và quy trình cập nhật hint cùng asset manifest.

HTTP 103 Early Hints biến thời gian backend đang suy nghĩ thành thời gian browser chuẩn bị, nhưng chỉ khi dự đoán đủ chính xác. Hãy bắt đầu với một stylesheet hoặc một preconnect chắc chắn, xác minh cache reuse và đo trên người dùng thật. Khi hint không tạo cải thiện rõ ràng, xóa nó cũng là một tối ưu.

Thảo luận

Bình luận 0

Đăng nhập để bình luận

Bạn cần có tài khoản để tham gia thảo luận và trả lời độc giả khác.

Đăng nhậpĐăng ký

Chưa có bình luận. Hãy là người đầu tiên chia sẻ ý kiến.