Tải trang nhanh hơn nhờ thời gian suy nghĩ của máy chủ nhờ tính năng Gợi ý sớm

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.

Kenji Baheux
Kenji Baheux
Barry Pollard
Barry Pollard

Gợi ý ban đầu là gì?

Trang web đã trở nên tinh vi hơn theo thời gian. Do đó, không có gì bất thường khi máy chủ cần thực hiện những công việc không quan trọng (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. 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.

Hình ảnh cho thấy khoảng thời gian chờ cho máy chủ là 200 mili giây giữa lượt tải trang và lượt tải các tài nguyên khác.
Nếu không có tính năng Gợi ý ban đầu: mọi thứ đều bị chặn trên máy chủ khi xác định cách phản hồi tài nguyên chính.

Gợi ý ban đầu 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, Gợi ý ban đầu giúp trình duyệt tận dụng lợi thế của "thời gian suy nghĩ của máy chủ" như vậy bằng cách thực hiện trước một số thao tác, nhờ đó tăng tốc độ tải trang.

Hình ảnh minh hoạ cách tính năng Gợi ý ban đầu cho phép trang gửi một phần câu trả lời.
Với Gợi ý ban đầu: máy chủ có thể phân phát một phần phản hồi kèm theo các gợi ý về tài nguyên trong khi xác định phản hồi cuối cùng

Trong một số trường hợp, hiệu suất cải thiện của Nội dung lớn nhất hiển thị có thể mất vài trăm mili giây (theo quan sát của ShopifyCloudflare) và nhanh hơn đến một giây, như được thấy trong phần so sánh trước và sau:

So sánh hai trang web.
Trước/sau khi so sánh các Gợi ý ban đầu trên một trang web thử nghiệm được thực hiện bằng WebPageTest (Moto G4 – DSL)

Cách sử dụng tính năng Gợi ý ban đầu

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ì mức độ hữu ích của Gợi ý ban đầu giảm khi người dùng di chuyển quanh trang web của bạn (tức là trình duyệt có nhiều khả năng có tất cả tài nguyên phụ cần thiết trong lần điều hướng thứ hai hoặc thứ ba). 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 hiển thị như JavaScript đồng bộ, biểu định kiểu hoặc thậm chí là phông chữ web. Tương tự, hãy tìm những nguồn gốc lưu trữ những tài nguyên phụ đóng góp nhiều vào chỉ số người dùng chính.

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 một cách đơn thuần các lệnh preconnectpreload từ HTML sang Gợi ý ban đầu có thể không tối ưu.

Khi sử dụng các tài nguyên này trong HTML, bạn thường muốn preconnect hoặc preload 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ẽ bị phát hiện muộn. Đối với tính năng Gợi ý ban đầu, bạn sẽ không có HTML. Vì vậy, bạn nên chuyển preconnect sang các miền quan trọng hoặc preload tài nguyên quan trọng mà có thể sẽ 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 tính năng 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 sử dụng tính năng Gợi ý ban đầu đối với những tài nguyên hoặc nguồn có thể đã lỗi thời hoặc không còn được tài nguyên chính sử dụng. Ví dụ: những 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 mối lo ngại này không chỉ áp dụng cho Gợi ý ban đầu mà chỉ áp dụng cho preload hoặc preconnect bất kỳ ở nơi nào chúng có thể xuất hiện. Đây là loại chi tiết được xử lý tốt nhất khi dùng tính năng tự động hoá hoặc tạo mẫu (ví dụ: một quy trình thủ công có nhiều khả năng dẫn đến việc 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 sẽ cần main.abcd100.css và đề xuất tải trước bằng cách sử dụng Gợi ý sớm:

103 Early Hints
Link: </main.abcd100.css>; rel=preload; as=style
[...]

Vài phút sau, trang web, bao gồm cả CSS đã liên kết đượ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 đã có trước 5 phiên bản (abcd105) của tài nguyên CSS 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, về phía máy chủ, hãy tìm các yêu cầu tài nguyên chính được gửi bởi các trình duyệt có hỗ trợ tính năng Gợi ý ban đầu và phản hồi ngay lập tức bằng 103 Gợi ý ban đầu. Trong phản hồi 103, hãy thêm các gợi ý kết nối trước và gợi ý tải trước có liên quan. Sau khi tài nguyên chính đã sẵn sàng, hãy tiếp tục bằng cách 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 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 những 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 đôi"). Mã này 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 ý ban đầu được hỗ trợ trong tất cả các trình duyệt chính, nhưng các lệnh có thể gửi trong Gợi ý ban đầu sẽ khác nhau tuỳ theo trình duyệt:

Hỗ trợ kết nối trước:

Hỗ trợ trình duyệt

  • 103
  • 103
  • 120
  • 17

Hỗ trợ tải trước:

Hỗ trợ trình duyệt

  • 103
  • 103
  • 123
  • x

Công cụ của Chrome cho nhà phát triển cũng hỗ trợ 103 Gợi ý ban đầu và bạn có thể xem tiêu đề Link trong các tài nguyên tài liệu:

Bảng điều khiển mạng hiển thị Tiêu đề Gợi ý ban đầu
Tiêu đề Gợi ý ban đầu Link xuất hiện trong Công cụ của Chrome cho nhà phát triển.

Xin lưu ý rằng để sử dụng các tài nguyên của Gợi ý ban đầu, bạn không được chọn Disable cache trong Công cụ cho nhà phát triển vì tính năng Gợi ý ban đầu sử dụng bộ nhớ đệm của trình duyệt. Đối với các tài nguyên được tải trước, trình khởi tạo sẽ hiển thị dưới dạng early-hintskích thước sẽ hiển thị dưới dạng (Disk cache):

Bảng điều khiển mạng hiển thị trình khởi tạo Gợi ý ban đầu
Các tài nguyên Gợi ý ban đầu có một trình khởi tạo early-hints và được tải từ bộ nhớ đệm của ổ đĩa.

Bạn cũng cần có một chứng chỉ đáng tin cậy để kiểm tra HTTPS.

Firefox (kể từ phiên bản 126) không hỗ trợ rõ ràng 103 Gợi ý ban đầu trong Công cụ cho nhà phát triển, nhưng các tài nguyên được tải bằng Gợi ý ban đầu không hiển thị thông tin Tiêu đề HTTP, đó là một chỉ báo chúng được tải qua Gợi ý ban đầu.

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:

Bật tính năng Gợi ý ban đầu một 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 đây, bạn có thể không cần phải triển khai Gợi ý ban đầu 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 gặp vấn đề đối với những ứng dụng không hỗ trợ tính năng Gợi ý ban đầu

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 ý ban đầu để phản hồi máy khách gửi tiêu đề yêu cầu HTTP sec-fetch-mode: navigate phải đảm bảo các gợi ý đó chỉ được gửi cho các ứng dụng mới hơn hiểu là đang chờ phản hồi tiếp theo. Ngoài ra, do Gợi ý ban đầu chỉ được hỗ trợ trong các yêu cầu điều hướng (xem các giới hạn hiện tại), điều này có thêm một lợi ích là tránh được việc gửi những thông tin này một cách không cần thiết trong các yêu cầu khác.

Ngoài ra, bạn chỉ nên gửi Gợi ý ban đầu qua kết nối HTTP/2 hoặc HTTP/3 và hầu hết các trình duyệt sẽ chỉ chấp nhận Gợi ý ban đầu 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 đã thực hiện yêu cầu trang nth 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 nghe có vẻ khác thường vì chúng tôi khuyên bạn nên tập trung vào các nguồn phụ hoặc nguồn phụ có mức độ ưu tiên cao, chặn hiển thị. Tuy nhiên, vào thời điểm khách truy cập điều hướng được một thời gian, rất có thể trình duyệt của họ đã có tất cả cá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ụ: bạn có thể sử dụng tính năng Gợi ý ban đầu để 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 của người dùng.

Hạn chế hiện tại

Dưới đây là những hạn chế 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ợ preconnectpreload (nghĩa là prefetch không được hỗ trợ).
  • 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 đó, bạn chỉ có thể tải trước những tài nguyên có thể lưu vào bộ nhớ đệm bằng cách sử dụng Gợi ý ban đầu, nếu không tài nguyên sẽ được tìm nạp 2 lần (một lần qua Gợi ý ban đầu và một lần nữa qua tài liệu). Trong Chrome, bộ nhớ đệm HTTP sẽ 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).

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ối 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 ý ban đầu bằng những chức 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 ý ban đầu được gửi trong các yêu cầu về tài nguyên phụ.
  • Gợi ý ban đầu được gửi trên các yêu cầu tài nguyên chính của iframe.
  • Hỗ trợ tìm nạp trước trong Gợi ý ban đầu.

Chúng tôi hoan nghênh ý 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 hơn nữa tính năng Gợi ý ban đầu.

Mối quan hệ với H2/Đẩy

Nếu đã quen thuộc với tính năng HTTP2/Đẩy không dùng nữa, bạn có thể thắc mắc về sự khác biệt của tính năng Gợi ý ban đầu. 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. Điều này nghe có vẻ đáng kinh ngạc, nhưng lại dẫn đến một nhược điểm chính về cấu trúc: với HTTP2/Push, vô cùng 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, điều này 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ộ 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ề mặt lý thuyết, Gợi ý ban đầu không bao gồm hết mọi trường hợp sử dụng mà HTTP2/Đẩy có thể giải quyết trên lý thuyết, nhưng chúng tôi tin rằng tính năng Gợi ý ban đầu là một giải pháp thiết thực hơn để tăng tốc độ điều hướng.

Hình thu nhỏ của Pierre Bamin.