Tìm hiểu cách máy chủ của bạn có thể gửi gợi ý cho trình duyệt về các tài nguyên phụ quan trọng.
Gợi ý sớm là gì?
Các trang web ngày càng trở nên phức tạp hơn theo thời gian. Do đó, không có gì lạ khi máy chủ cần thực hiện công việc không hề đơn giản (ví dụ: truy cập vào cơ sở dữ liệu hoặc CDN truy cập vào máy chủ gốc) để tạo HTML cho trang được yêu cầu. Rất tiếc, tính năng "thời gian chờ của máy chủ" này làm tăng độ trễ trước khi trình duyệt có thể bắt đầu hiển thị trang. Thật vậy, kết nối sẽ ở trạng thái rảnh trong khoảng thời gian máy chủ chuẩn bị phản hồi.
Gợi ý sớm là một mã trạng thái HTTP (103 Early Hints
) dùng để gửi phản hồi HTTP sơ bộ trước phản hồi cuối cùng. Điều này cho phép máy chủ gửi gợi ý cho trình duyệt về các tài nguyên phụ quan trọng (ví dụ: biểu định kiểu cho trang, JavaScript quan trọng) hoặc nguồn gốc có thể được trang sử dụng, trong khi máy chủ đang bận tạo tài nguyên chính. Trình duyệt có thể sử dụng các gợi ý đó để khởi động kết nối và yêu cầu tài nguyên phụ trong khi chờ tài nguyên chính. Nói cách khác, tính năng Gợi ý sớm giúp trình duyệt tận dụng "thời gian suy nghĩ của máy chủ" đó bằng cách thực hiện một số công việc trước, nhờ đó tăng tốc độ tải trang.
Trong một số trường hợp, hiệu suất của Thời gian hiển thị nội dung lớn nhất có thể cải thiện từ vài trăm mili giây, như Shopify và Cloudflare đã quan sát được, và nhanh hơn đến một giây, như trong bảng so sánh trước và sau đây:
Cách sử dụng Gợi ý sớm
Bước đầu tiên để tận dụng tính năng Gợi ý ban đầu bao gồm việc xác định các trang đích hàng đầu, tức là những trang mà người dùng thường bắt đầu khi họ truy cập vào trang web của bạn. Đây có thể là trang chủ hoặc các trang thông tin sản phẩm phổ biến nếu bạn có nhiều người dùng đến từ các trang web khác. Lý do các điểm truy cập này quan trọng hơn các trang khác là vì tính hữu ích của Gợi ý sớm sẽ giảm khi người dùng di chuyển trên trang web của bạn (tức là trình duyệt có nhiều khả năng sẽ có tất cả tài nguyên phụ cần thiết trên lần điều hướng thứ hai hoặc thứ ba tiếp theo). Bạn cũng nên tạo ấn tượng ban đầu thật tốt!
Giờ đây, khi bạn đã có danh sách trang đích ưu tiên này, bước tiếp theo là xác định những nguồn gốc hoặc tài nguyên phụ nào sẽ phù hợp để gợi ý về preconnect
hoặc preload
. Thông thường, đó sẽ là các nguồn gốc và tài nguyên phụ đóng góp nhiều nhất vào chỉ số người dùng chính, chẳng hạn như Nội dung lớn nhất hiển thị hoặc Nội dung đầu tiên hiển thị. Cụ thể hơn, hãy tìm các tài nguyên phụ chặn kết xuất như JavaScript đồng bộ, các kiểu phông chữ hoặc thậm chí là phông chữ web. Tương tự, hãy tìm các nguồn gốc lưu trữ tài nguyên phụ đóng góp nhiều vào các chỉ số chính của người dùng.
Ngoài ra, xin lưu ý rằng nếu các tài nguyên chính của bạn đang dùng preconnect
hoặc preload
, thì bạn có thể xem xét những nguồn gốc hoặc tài nguyên này trong số các đề xuất cho tính năng Gợi ý ban đầu. Xem cách tối ưu hoá LCP để biết thêm chi tiết. Tuy nhiên, việc sao chép đơn thuần các lệnh preconnect
và preload
từ HTML sang Gợi ý sớm có thể không tối ưu.
Khi sử dụng các thuộc tính này trong HTML, bạn thường muốn preconnect
hoặc preload
các tài nguyên mà Trình quét tải trước sẽ không phát hiện được trong HTML, ví dụ: phông chữ hoặc hình nền sẽ được phát hiện muộn. Đối với Gợi ý sớm, bạn sẽ không có HTML nên bạn có thể preconnect
đến các miền quan trọng hoặc preload
tài nguyên quan trọng có thể sẽ được phát hiện sớm trong HTML – ví dụ: tải trước main.css
hoặc app.js
. Ngoài ra, không phải trình duyệt nào cũng hỗ trợ preload
cho Gợi ý sớm – hãy xem phần Hỗ trợ trình duyệt.
Bước thứ hai là giảm thiểu rủi ro khi sử dụng Gợi ý sớm trên các tài nguyên hoặc nguồn gốc có thể đã lỗi thời hoặc không còn được tài nguyên chính sử dụng. Ví dụ: các tài nguyên thường xuyên được cập nhật và tạo phiên bản (ví dụ: example.com/css/main.fa231e9c.css
) có thể không phải là lựa chọn tốt nhất. Xin lưu ý rằng vấn đề này không chỉ dành riêng cho Gợi ý sớm, mà còn áp dụng cho mọi preload
hoặc preconnect
bất cứ nơi nào chúng có thể xuất hiện. Đây là loại thông tin chi tiết tốt nhất để xử lý bằng tính năng tự động hoá hoặc tạo mẫu (ví dụ: quy trình thủ công có nhiều khả năng dẫn đến URL phiên bản hoặc hàm băm không khớp giữa preload
và thẻ HTML thực tế sử dụng tài nguyên).
Ví dụ: hãy xem xét quy trình sau:
GET /main.html
Host: example.com
User-Agent: [....] Chrome/103.0.0.0 [...]
Máy chủ dự đoán rằng main.abcd100.css
sẽ cần thiết và đề xuất tải trước tệp đó bằng tính năng Gợi ý sớm:
103 Early Hints
Link: </main.abcd100.css>; rel=preload; as=style
[...]
Vài giây sau, trang web, bao gồm cả CSS được liên kết, sẽ được phân phát. Rất tiếc, tài nguyên CSS này thường xuyên được cập nhật và tài nguyên chính đã đi trước 5 phiên bản (abcd105
) so với tài nguyên CSS được dự đoán (abcd100
).
200 OK
[...]
<HTML>
<head>
<title>Example</title>
<link rel="stylesheet" href="/main.abcd105.css">
Nhìn chung, hãy nhắm đến các tài nguyên và nguồn gốc khá ổn định và phần lớn độc lập với kết quả của tài nguyên chính. Nếu cần, bạn có thể cân nhắc việc chia đôi các tài nguyên chính: một phần ổn định được thiết kế để dùng với tính năng Gợi ý ban đầu và một phần linh hoạt hơn sẽ được tìm nạp sau khi trình duyệt nhận được tài nguyên chính:
<HTML>
<head>
<title>Example</title>
<link rel="stylesheet" href="/main.css">
<link rel="stylesheet" href="/experimental.3eab3290.css">
Cuối cùng, ở phía máy chủ, hãy tìm các yêu cầu tài nguyên chính do các trình duyệt được biết là hỗ trợ Gợi ý sớm gửi và phản hồi ngay lập tức bằng 103 Gợi ý sớm. Trong phản hồi 103, hãy thêm các gợi ý liên quan về tính năng kết nối trước và tải trước. Sau khi tài nguyên chính đã sẵn sàng, hãy tiếp tục bằng phản hồi thông thường (ví dụ: 200 OK nếu thành công). Để có khả năng tương thích ngược, bạn cũng nên đưa các tiêu đề HTTP Link
vào phản hồi cuối cùng, thậm chí có thể tăng cường bằng các tài nguyên quan trọng đã xuất hiện rõ ràng trong quá trình tạo tài nguyên chính (ví dụ: phần động của tài nguyên chính nếu bạn làm theo đề xuất "chia thành hai"). Mã sẽ có dạng như sau:
GET /main.html
Host: example.com
User-Agent: [....] Chrome/103.0.0.0 [...]
103 Early Hints
Link: <https://fonts.google.com>; rel=preconnect
Link: </main.css>; rel=preload; as=style
Link: </common.js>; rel=preload; as=script
Đợi vài phút sau:
200 OK
Content-Length: 7531
Content-Type: text/html; charset=UTF-8
Content-encoding: br
Link: <https://fonts.google.com>; rel=preconnect
Link: </main.css>; rel=preload; as=style
Link: </common.js>; rel=preload; as=script
Link: </experimental.3eab3290.css>; rel=preload; as=style
<HTML>
<head>
<title>Example</title>
<link rel="stylesheet" href="/main.css">
<link rel="stylesheet" href="/experimental.3eab3290.css">
<script src="/common.js"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
Hỗ trợ trình duyệt
Mặc dù 103 Gợi ý sớm được hỗ trợ trong tất cả các trình duyệt chính, nhưng các lệnh có thể được gửi trên Gợi ý sớm lại khác nhau tuỳ theo trình duyệt:
Hỗ trợ kết nối trước:
Hỗ trợ trình duyệt
Hỗ trợ tải trước:
Hỗ trợ trình duyệt
Công cụ của Chrome cho nhà phát triển cũng có 103 tính năng hỗ trợ Gợi ý sớm và bạn có thể xem các tiêu đề Link
trên tài nguyên tài liệu:
Lưu ý để sử dụng tài nguyên Gợi ý sớm, bạn không được đánh dấu Disable cache
trong DevTools vì Gợi ý sớm sử dụng bộ nhớ đệm của trình duyệt. Đối với tài nguyên được tải trước, trình khởi tạo sẽ hiển thị dưới dạng early-hints
và kích thước là (Disk cache)
:
Bạn cũng cần có chứng chỉ đáng tin cậy để kiểm thử HTTPS.
Firefox (kể từ phiên bản 126) không hỗ trợ rõ ràng 103 Gợi ý sớm trong DevTools, nhưng các tài nguyên được tải bằng Gợi ý sớm không hiển thị thông tin Tiêu đề HTTP, đây là một chỉ báo cho biết các tài nguyên đó đã được tải thông qua Gợi ý sớm.
Hỗ trợ máy chủ
Dưới đây là tóm tắt nhanh về mức độ hỗ trợ của tính năng Gợi ý ban đầu trong số các phần mềm máy chủ HTTP của phần mềm nguồn mở phổ biến:
- Apache: được hỗ trợ bằng mod_http2.
- H2O: được hỗ trợ.
- NGINX: mô-đun thử nghiệm.
- Node: được hỗ trợ kể từ phiên bản 18.11.0 cho http và http2
Bật tính năng Gợi ý sớm theo cách dễ dàng hơn
Nếu đang sử dụng một trong các CDN hoặc nền tảng sau, bạn có thể không cần triển khai Gợi ý sớm theo cách thủ công. Hãy tham khảo tài liệu trực tuyến của nhà cung cấp giải pháp để tìm hiểu xem họ có hỗ trợ tính năng Gợi ý ban đầu hay không, hoặc tham khảo danh sách chưa đầy đủ tại đây:
Cách tránh các vấn đề cho ứng dụng không hỗ trợ tính năng Gợi ý sớm
Các phản hồi HTTP thông tin trong phạm vi 100 là một phần của tiêu chuẩn HTTP, nhưng một số ứng dụng hoặc bot cũ có thể gặp khó khăn với các phản hồi này vì trước khi ra mắt 103 Gợi ý sớm, chúng hiếm khi được dùng để duyệt web thông thường.
Chỉ phát 103 Gợi ý sớm để phản hồi những ứng dụng gửi tiêu đề yêu cầu HTTP sec-fetch-mode: navigate
. Điều này sẽ đảm bảo rằng các gợi ý đó chỉ được gửi cho những ứng dụng mới hơn hiểu được việc chờ phản hồi tiếp theo. Ngoài ra, vì Gợi ý sớm chỉ được hỗ trợ trên các yêu cầu điều hướng (xem các hạn chế hiện tại), nên việc này có thêm lợi ích là tránh gửi các gợi ý này một cách không cần thiết trên các yêu cầu khác.
Ngoài ra, bạn chỉ nên gửi Gợi ý sớm qua các kết nối HTTP/2 hoặc HTTP/3 và hầu hết trình duyệt sẽ chỉ chấp nhận các gợi ý đó qua các giao thức đó.
Mẫu nâng cao
Nếu đã áp dụng đầy đủ tính năng Gợi ý sớm cho các trang đích chính và đang tìm kiếm thêm cơ hội, bạn có thể quan tâm đến mẫu nâng cao sau đây.
Đối với những khách truy cập đã thực hiện yêu cầu trang thứ n trong hành trình điển hình của người dùng, bạn có thể điều chỉnh phản hồi của tính năng Gợi ý ban đầu cho phù hợp với nội dung ở cấp độ thấp hơn và sâu hơn trên trang, nói cách khác là sử dụng tính năng Gợi ý ban đầu trên các tài nguyên có mức độ ưu tiên thấp hơn. Điều này có vẻ như trái ngược với trực giác vì chúng tôi đề xuất tập trung vào các tài nguyên phụ hoặc nguồn gốc có mức độ ưu tiên cao, chặn kết xuất. Tuy nhiên, khi khách truy cập đã di chuyển một lúc, rất có thể trình duyệt của họ đã có tất cả tài nguyên quan trọng. Từ đó, bạn nên chuyển sự chú ý sang các tài nguyên có mức độ ưu tiên thấp hơn. Ví dụ: điều này có thể có nghĩa là sử dụng Gợi ý sớm để tải hình ảnh sản phẩm hoặc JS/CSS bổ sung chỉ cần thiết cho các hoạt động tương tác ít phổ biến hơn của người dùng.
Các hạn chế hiện tại
Sau đây là các hạn chế của tính năng Gợi ý sớm được triển khai trong Chrome:
- Chỉ dành cho các yêu cầu điều hướng (tức là tài nguyên chính cho tài liệu cấp cao nhất).
- Chỉ hỗ trợ
preconnect
vàpreload
(tức là không hỗ trợprefetch
). - Gợi ý ban đầu, theo sau là chuyển hướng nhiều nguồn gốc trong phản hồi cuối cùng sẽ dẫn đến việc Chrome loại bỏ các tài nguyên và kết nối nhận được bằng tính năng Gợi ý ban đầu.
- Các tài nguyên được tải trước bằng tính năng Gợi ý ban đầu sẽ được lưu trữ trong bộ nhớ đệm HTTP và được trang truy xuất từ đó sau này. Do đó, chỉ những tài nguyên có thể lưu vào bộ nhớ đệm mới có thể được tải trước bằng tính năng Gợi ý sớm, nếu không tài nguyên sẽ được tìm nạp hai lần (một lần bằng tính năng Gợi ý sớm và một lần nữa bằng tài liệu). Trong Chrome, bộ nhớ đệm HTTP bị tắt đối với các chứng chỉ HTTPS không đáng tin cậy (ngay cả khi bạn tiếp tục tải trang).
- Tính năng tải trước hình ảnh thích ứng (sử dụng
imagesrcset
,imagesizes
hoặcmedia
) không được hỗ trợ bằng cách sử dụng tiêu đề<link>
HTTP vì khung nhìn không được xác định cho đến khi tài liệu được tạo. Điều này có nghĩa là bạn không thể sử dụng 103 Sớm để tải trước hình ảnh thích ứng và có thể tải hình ảnh không chính xác khi dùng cho mục đích này. Hãy tham khảo cuộc thảo luận về các đề xuất về cách xử lý vấn đề này hiệu quả hơn.
Các trình duyệt khác cũng có những hạn chế tương tự và như đã lưu ý trước đó, một số trình duyệt còn hạn chế 103 gợi ý sớm chỉ ở preconnect
.
Tiếp theo là gì?
Tuỳ thuộc vào mức độ quan tâm của cộng đồng, chúng tôi có thể tăng cường việc triển khai tính năng Gợi ý sớm bằng các tính năng sau:
- Gợi ý ban đầu dành cho các tài nguyên không thể lưu vào bộ nhớ đệm bằng cách sử dụng bộ nhớ đệm của bộ nhớ thay vì bộ nhớ đệm HTTP.
- Gợi ý sớm được gửi trên các yêu cầu tài nguyên phụ.
- Gợi ý sớm được gửi trên các yêu cầu tài nguyên chính của iframe.
- Hỗ trợ tính năng tải trước trong tính năng Gợi ý sớm.
Chúng tôi rất mong nhận được ý kiến đóng góp của bạn về những khía cạnh cần ưu tiên và cách cải thiện thêm tính năng Gợi ý sớm.
Mối quan hệ với H2/Push
Nếu đã quen thuộc với tính năng HTTP2/Push không còn được dùng nữa, bạn có thể thắc mắc về sự khác biệt giữa tính năng Gợi ý sớm. Mặc dù tính năng Gợi ý ban đầu yêu cầu trình duyệt phải thực hiện một vòng khứ hồi để bắt đầu tìm nạp các tài nguyên phụ quan trọng, nhưng với HTTP2/Push, máy chủ có thể bắt đầu đẩy các tài nguyên phụ cùng với phản hồi. Mặc dù nghe có vẻ tuyệt vời, nhưng điều này dẫn đến một nhược điểm chính về cấu trúc: với HTTP2/Push, rất khó để tránh đẩy các tài nguyên phụ mà trình duyệt đã có. Hiệu ứng "đẩy quá mức" này dẫn đến việc sử dụng băng thông mạng kém hiệu quả hơn, từ đó cản trở đáng kể lợi ích về hiệu suất. Nhìn chung, dữ liệu của Chrome cho thấy HTTP2/Push thực tế không đạt hiệu suất như mong đợi trên web.
Ngược lại, trong thực tế, tính năng Gợi ý ban đầu hoạt động hiệu quả hơn vì nó kết hợp khả năng gửi phản hồi sơ bộ cùng với gợi ý để trình duyệt có thể tìm nạp hoặc kết nối với những dữ liệu mà trình duyệt thực sự cần. Mặc dù về lý thuyết, tính năng Gợi ý sớm không bao gồm tất cả các trường hợp sử dụng mà HTTP2/Push có thể giải quyết, nhưng chúng tôi tin rằng tính năng Gợi ý sớm là một giải pháp thực tế hơn để tăng tốc điều hướng.
Hình thu nhỏ của Pierre Bamin.