Categories Tải trước

Thành lập các kết nối mạng sớm (preconnect) để cải thiện tốc độ website

Trong bài viết này chúng ta sẽ cùng học cách sử dụng các kiểu gợi ý tài nguyên rel=preconnectrel=dns-prefetch.

Trước khi trình duyệt có thể yêu cầu một tài nguyên từ máy chủ, nó phải thành lập kết nối. Thành lập một kết nối bảo mật (secure connection) liên quan đến ba bước:

  • Tìm kiếm tên miền và phân giải nó thành địa chỉ IP;
  • Thiết lập kết nối tới máy chủ;
  • Mã hóa kết nối đó để nó bảo mật.

Trong từng bước trên trình duyệt gửi một phần dữ liệu tới máy chủ, và máy chủ gửi lại một phản hồi. Hành trình này, từ máy chủ gốc đến địa chỉ cần đến và quay ngược trở lại, được gọi là khứ hồi (round trip).

Phụ thuộc vào tình trạng kết nối, một vòng khứ hồi có thể cần một lượng thời gian đáng kể. Quá trình thiết lập kết nối có thể liên quan đến ba vòng khứ hồi-và nhiều hơn nữa trong các trường hợp chưa được tối ưu.

Nếu bạn thực hiện kiểu kết nối ‘đi tắt đón đầu’ cho tất cả, bạn sẽ giúp các ứng dụng nhanh hơn nhiều. Bài viết này giải thích cách đạt được điều đó với hai gợi ý tài nguyên: <link rel=preconnect><link rel=dns-prefetch>.


Thành lập kết nối sớm với rel=preconnect

Các trình duyệt hiện đại cố gắng hết sức để biết các kết nối nào sẽ cần, nhưng chúng không thể nào dự đoán chính xác tất cả được. Tin tốt là bạn có thể cung cấp cho chúng gợi ý tài nguyên (resource hint).

Thêm rel=preconnect vào thẻ <link> để thông báo với trình duyệt rằng trang của bạn có ý định thành lập kết nối tới tên miền khác, và bạn muốn quá trình này bắt đầu càng sớm càng tốt. Các tài nguyên sẽ được tải nhanh hơn bởi vì quá trình thiết lập đã được hoàn thành trước thời điểm trình duyệt yêu cầu chúng.

Các gợi ý tài nguyên (resource hints) có tên như vậy bởi vì chúng không phải là các hướng dẫn bắt buộc. Chúng cung cấp thông tin về cái mà bạn muốn xảy ra, nhưng điều này cuối cùng có xảy ra hay không hoàn toàn phụ thuộc vào trình duyệt có quyết định thực thi chúng không. Cài đặt và giữ kết nối mở tốn nhiều công sức, vì thế trình duyệt có thể chọn bỏ qua các gợi ý tài nguyên hoặc thực thi chúng một phần phụ thuộc vào tình huống cụ thể.

Thông báo với trình duyệt ý định của bạn bằng cách đơn giản thêm một thẻ <link> vào trang:

<link rel="preconnect" href="https://example.com">
sự khác biệt giữa có preconnect và không có preconnect
Nhờ việc thực hiện kết nối song song (hình bên dưới), thời gian tải trang đã được giảm xuống so với thông thường (hình bên trên)

Bạn có thể giảm thời gian tải trang từ 100-500ms bằng cách thực hiện các kết nối sớm tới máy chủ gốc quan trọng của bên thứ ba (third-party). Con số trên có vẻ nhỏ, nhưng chúng có thể tạo ra sự khác biệt trong nhận thức của người dùng về hiệu suất, tốc độ trang. Ví dụ trang chrome.com cải thiện được Time To Interactive gần một giây nhờ việc thực hiện kết nối sớm tới máy chủ gốc quan trọng.


Các trường hợp sử dụng rel=preconnect

Biết chúng đến từ đâu, nhưng không biết phải tìm nạp cái gì

Vì phụ thuộc vào các phiên bản, đôi khi bạn gặp phải tình huống mà bản thân biết các yêu cầu tài nguyên đến từ CDN cụ thể, nhưng không biết chính xác đường dẫn của nó.

Ví dụ về phiên bản URL
Ví dụ về phiên bản URL

Trường hợp phổ biến khác là tải ảnh từ CDN ảnh, khi mà đường dẫn chính xác của ảnh phụ thuộc vào truy vấn media hoặc các kiểm tra chức năng runtime trên trình duyệt người dùng.

Một ví dụ về URL CDN cho ảnh
Một ví dụ về URL CDN cho ảnh, trong đường dẫn ngoài thông tin thông thường nó còn có thêm thông tin về key, chất lượng, kích cỡ

Trong những tình huống như vậy, nếu tài nguyên bạn muốn tìm nạp (fetching) là quan trọng, bạn muốn tiết kiệm càng nhiều thời gian càng tốt bằng cách kết nối trước với máy chủ. Trình duyệt không tải file cho đến khi trang của bạn yêu cầu nó, nhưng ít nhất nó có thể xử lý trước được nhiệm vụ kết nối, tiết kiệm cho người dùng không phải đợi vài vòng khứ hồi.

Streaming media (phát video, nhạc, vân vân từ bên thứ ba)

Một ví dụ khác khi bạn muốn tiết kiệm thời gian trong pha kết nối, nhưng không nhất thiết phải nhận nội dung ngay lập tức, là khi bạn phát media (nhạc, video, vân vân) từ một máy chủ gốc khác.

Phụ thuộc vào cách trang của bạn xử lý nội dung stream, bạn có thể muốn đợi cho đến khi mã của bạn được tải xong và sẵn sàng xử lý stream. Kết nối trước giúp bạn cắt thời gian chờ đợi cho một vòng khứ hồi một khi bạn đã sẵn sàng bắt đầu tìm nạp.


Cách triển khai rel=preconnect

Để bắt đầu sử dụng preconnect, bạn thêm thẻ <link> vào phần <head> của tài liệu.

<head>
    <link rel="preconnect" href="https://example.com">
</head>

Kết nối trước chỉ có hiệu quả với các tên miền khác với tên miền gốc của bạn, vì thế bạn không nên sử dụng nó cho chính tên miền của bạn (ví dụ trang web của tôi là kiencang.net, tôi không cần preconnect đến kiencang.net nữa).

Lưu ý: Chỉ preconnect tới các tên miền quan trọng mà bạn sẽ sử dụng sớm, bởi vì trình duyệt sẽ đóng bất kỳ kết nối nào không được sử dụng trong vòng 10 giây. Các kết nối trước không cần thiết có thể làm trì hoãn các tài nguyên quan trọng khác, vì thế giới hạn số lượng tên miền được kết nối trước và nên kiểm tra ảnh hưởng mà preconnect tạo ra.

Bạn cũng có thể sử dụng preconnect thông qua Link HTTP header:

Link: <https://example.com/>; rel=preconnect

Lợi ích của việc chỉ định gợi ý preconnect trong HTTP header là nó không phải dựa trên các mã đánh dấu đã được phân tích cú pháp, và nó có thể được kích hoạt bởi các yêu cầu cho stylesheets, scripts, và nhiều cái khác. Lấy ví dụ, Google Fonts gửi một Link header trong phản hồi stylesheets để kết nối sớm (preconnect) với tên miền host các file font.

Một số kiểu tài nguyên, chẳng hạn như font được tải trong chế độ vô danh (anonymous mode). Với những tài nguyên như vậy bạn phải thiết lập thuộc tính crossorigin với gợi ý preconnect:

<link rel="preconnect" href="https://example.com/ComicSans" crossorigin>

Nếu bạn bỏ qua thuộc tính crossorigin, trình duyệt sẽ chỉ thực hiện tìm kiếm DNS mà thôi.


Phân giải tên miền sớm với rel=dns-prefetch

Bạn nhớ tên miền thông qua tên của chúng, nhưng máy chủ nhớ chúng thông qua địa chỉ IP. Điều này giải thích tại sao hệ thông phân giải tên miền DNS lại tồn tại. Trình duyệt sử dụng DNS để chuyển tên miền thành địa chỉ IP. Quá trình này- tức phân giải tên miền- là bước đầu tiên để thành lập một kết nối.

Nếu trang cần tạo kết nối tới nhiều tên miền của bên thứ ba, kết nối trước với tất cả chúng sẽ phản tác dụng. Gợi ý preconnect áp dụng tốt nhất chỉ cho các kết nối quan trọng nhất. Với phần còn lại, bạn hãy sử dụng <link rel=dns-prefetch> để tiết kiệm thời gian trong bước đầu tiên- tìm kiếm DNS, cái thường mất từ 20-120ms.

Phân giải trước DNS bắt đầu tương tự như preconnect: bằng cách thêm thẻ <link> vào phần <head> của tài liệu.

<link rel="dns-prefetch" href="http://example.com">

Trình duyệt hỗ trợ cho dns-prefetch hơi khác so với các hỗ trợ dành cho preconnect, vì thế dns-prefetch có thể được dùng như dự phòng (fallback) cho các trình duyệt không hỗ trợ preconnect.

Hãy làm như sau:

<link rel="preconnect" href="http://example.com">
<link rel="dns-prefetch" href="http://example.com">

Để triển khai kỹ thuật dự phòng, bạn hãy sử dụng các thẻ link riêng biệt.

Không nên làm như dưới đây:

<link rel="preconnect dns-prefetch" href="http://example.com">

Triển khai dự phòng dns-prefetch nằm cùng thẻ <link> gây ra lỗi trong trình duyệt Safari khi mà preconnect sẽ bị bỏ qua.


Kết luận

Hai kiểu gợi ý tài nguyên trên hữu ích trong việc cải thiện tốc độ trang khi bạn biết bạn sẽ tải cái gì đó sớm từ tên miền của bên thứ ba, nhưng bạn lại không biết chính xác URL của tài nguyên. Ví dụ gồm CDN phân phối các thư viện JavaScript, các ảnh hoặc font. Hãy chú ý đến những hạn chế, sử dụng preconnect chỉ cho các tài nguyên quan trọng nhất, dựa vào dns-fetch cho phần còn lại, và luôn luôn đo đạc ảnh hưởng trong thế giới thực (real-world).

(Dịch từ bài viết: Establish network connections early to improve perceived page speed, tác giả: Milica Mihajlija, trang web[.]dev)


Bonus cho người dùng WordPress

Để sử dụng preconnect hiệu quả trên WordPress bạn cần 2 thứ:

  • Biết rõ trang cần tài nguyên của bên thứ ba nào. Có hai công cụ mà bạn nên kết hợp, đó là tab Network trong công cụ dành cho nhà phát triển của Chrome (hiển thị chi tiết quá trình tải), và Tool Pingdom (rất trực quan).
  • Sử dụng plugin để preconnect các tài nguyên tương ứng trên trang cụ thể, vì thường thì không phải trang nào cũng cần preconnect đến cùng một tài nguyên, ví dụ như có trang nhúng video YouTube, có trang không, do vậy việc preconnect đến các tài nguyên tương ứng của YouTube phụ thuộc vào trang cụ thể có nhúng video hay không.

Plugin mà bạn cần là: SOGO Add Script to Individual Pages Header Footer – nó hay là vì bạn có thể thêm vào khu vực <header> cho cụ thể từng trang mà bạn muốn (các công cụ thông thường khác sẽ bổ sung vào header cho tất cả các trang). Nhờ thế mà bạn tùy biến được cho từng trang riêng biệt.

thêm mã tùy chỉnh link preconnect vào trang cụ thể trên WordPress
Dòng cuối bị thiếu thuộc tính crossorigin, vì đây là font

Công cụ tuy đơn giản nhưng rất hữu ích, nó cũng hoạt động tốt. Điểm trừ duy nhất là nhà phát triển plugin có vẻ khá cẩu thả khi viết phần mô tả cho nó.

Back to Top