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 ý ban đầu 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, "thời gian suy nghĩ của máy chủ" này dẫn đến độ trễ thêm trước khi trình duyệt có thể bắt đầu hiển thị trang. Trên thực tế, kết nối sẽ chuyển sang trạng thái rảnh miễn là 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 ý đến trình duyệt về các tài nguyên phụ quan trọng (ví dụ: trang kiểu cho trang, JavaScript quan trọng) hoặc nguồn gốc mà trang có thể 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 ý sớm là 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 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 tốt ngay từ đầu!
Giờ đây, bạn đã có danh sách trang đích được ưu tiên này, bước tiếp theo là xác định nguồn gốc hoặc tài nguyên phụ nào sẽ là ứng cử viên phù hợp cho gợi ý 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 các chỉ số chính của người dùng, chẳng hạn như Thời gian hiển thị nội dung lớn nhất hoặc Thời gian hiển thị nội dung đầu tiên. 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 đã sử dụng preconnect
hoặc preload
, thì bạn có thể xem xét các nguồn gốc hoặc tài nguyên này trong số các đề xuất cho Gợi ý sớm. 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 các tài nguyên chính thành hai phần: một phần ổn định được thiết kế để sử dụng với Gợi ý sớm và một phần linh động hơn để 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
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 nhà cung cấp đó có hỗ trợ tính năng Gợi ý sớm hay không, hoặc tham khảo danh sách không đầ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
Phản hồi HTTP cung cấp 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 những phản hồi này vì trước khi ra mắt 103 Gợi ý ban đầu, chúng hiếm khi được dùng để duyệt web chung.
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 đó.
Hình mở khoá nâng cao
Nếu đã áp dụng đầy đủ Gợi ý ban đầu cho các trang đích chính của mì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.
Đối với những khách truy cập đang ở yêu cầu trang n trong hành trình người dùng thông thường, bạn nên điều chỉnh phản hồi Gợi ý sớm cho nội dung ở vị trí thấp hơn và sâu hơn trong trang, tức là sử dụng Gợi ý sớm 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. Sau đó, bạn có thể chuyển sự chú ý của mình sang những 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.
Hạn chế hiện tại
Dưới đây là những giới hạn của tính năng Gợi ý ban đầu khi đượ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 của 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 ý sớm theo sau là lệnh chuyển hướng nhiều nguồn gốc trong phản hồi cuối cùng sẽ khiến Chrome loại bỏ các tài nguyên và kết nối mà Chrome đã thu thập được bằng Gợi ý sớm.
- Các tài nguyên được tải trước bằng tính năng Gợi ý sớm đượ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 gợi ý 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 sử 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ũng hạn chế hơn nữa việc sử dụng 103 gợi ý ban đầu thành 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 ý sớm 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 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 ý sớm yêu cầu trình duyệt thực hiện một lượt truy cập trả về để 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.