Tải trước các nội dung quan trọng để cải thiện tốc độ tải

Khi bạn mở một trang web, trình duyệt sẽ yêu cầu tài liệu HTML từ một máy chủ, phân tích cú pháp nội dung của tài liệu đó và gửi các yêu cầu riêng biệt cho mọi tài nguyên được tham chiếu. Là nhà phát triển, bạn đã biết tất cả tài nguyên mà trang của mình cần và tài nguyên nào quan trọng nhất. Bạn có thể sử dụng kiến thức đó để yêu cầu các tài nguyên quan trọng trước và tăng tốc quá trình tải. Bài đăng này giải thích cách thực hiện việc đó bằng <link rel="preload">.

Cách hoạt động của tính năng tải trước

Tải trước phù hợp nhất với các tài nguyên thường được trình duyệt phát hiện muộn.

Ảnh chụp màn hình bảng điều khiển Mạng trong Công cụ của Chrome cho nhà phát triển.
Trong ví dụ này, phông chữ Pacifico được xác định trong tệp định kiểu bằng quy tắc @font-face. Trình duyệt chỉ tải tệp phông chữ sau khi tải xuống và phân tích cú pháp xong tệp định kiểu.

Bằng cách tải trước một tài nguyên nhất định, bạn đang cho trình duyệt biết rằng bạn muốn tìm nạp tài nguyên đó sớm hơn so với thời điểm trình duyệt phát hiện ra tài nguyên đó vì bạn chắc chắn rằng tài nguyên đó rất quan trọng đối với trang hiện tại.

Ảnh chụp màn hình bảng điều khiển Mạng trong Chrome DevTools sau khi áp dụng tính năng tải trước.
Trong ví dụ này, phông chữ Pacifico được tải trước, vì vậy, quá trình tải xuống diễn ra song song với tệp kiểu.

Chuỗi yêu cầu quan trọng thể hiện thứ tự các tài nguyên được trình duyệt ưu tiên và tìm nạp. Lighthouse xác định các thành phần ở cấp thứ ba của chuỗi này là các thành phần được phát hiện muộn. Bạn có thể sử dụng quy trình kiểm tra Tải trước các yêu cầu chính để xác định tài nguyên cần tải trước.

Quy trình kiểm tra yêu cầu khoá tải trước của Lighthouse.

Bạn có thể tải trước tài nguyên bằng cách thêm thẻ <link>rel="preload" vào đầu tài liệu HTML:

<link rel="preload" as="script" href="critical.js">

Trình duyệt lưu các tài nguyên được tải trước vào bộ nhớ đệm để có thể sử dụng ngay khi cần. (Trình duyệt này không thực thi tập lệnh hoặc áp dụng các tệp kiểu.)

Các gợi ý về tài nguyên, ví dụ: preconnectprefetch, được thực thi khi trình duyệt thấy phù hợp. Mặt khác, preload là bắt buộc đối với trình duyệt. Các trình duyệt hiện đại đã khá tốt trong việc ưu tiên tài nguyên, đó là lý do bạn cần sử dụng preload một cách tiết kiệm và chỉ tải trước những tài nguyên quan trọng nhất.

Tệp tải trước không dùng đến sẽ kích hoạt cảnh báo của Bảng điều khiển trong Chrome, khoảng 3 giây sau sự kiện load.

Cảnh báo của Bảng điều khiển Công cụ của Chrome cho nhà phát triển về tài nguyên được tải trước nhưng không sử dụng.

Trường hợp sử dụng

Tải trước các tài nguyên được xác định trong CSS

Phông chữ được xác định bằng quy tắc @font-face hoặc hình nền được xác định trong tệp CSS sẽ không được phát hiện cho đến khi trình duyệt tải xuống và phân tích cú pháp các tệp CSS đó. Việc tải trước các tài nguyên này đảm bảo rằng chúng được tìm nạp trước khi tải tệp CSS xuống.

Tải trước tệp CSS

Nếu đang sử dụng phương pháp CSS quan trọng, bạn sẽ chia CSS thành hai phần. CSS quan trọng cần thiết để hiển thị nội dung trong màn hình đầu tiên được nội tuyến trong <head> của tài liệu và CSS không quan trọng thường được tải lười bằng JavaScript. Việc chờ JavaScript thực thi trước khi tải CSS không quan trọng có thể gây ra độ trễ trong quá trình kết xuất khi người dùng cuộn. Vì vậy, bạn nên sử dụng <link rel="preload"> để bắt đầu tải xuống sớm hơn.

Tải trước tệp JavaScript

Vì trình duyệt không thực thi các tệp được tải trước, nên tính năng tải trước rất hữu ích để tách biệt quá trình tìm nạp khỏi thực thi. Điều này có thể cải thiện các chỉ số như Thời gian phản hồi. Tính năng tải trước hoạt động hiệu quả nhất nếu bạn phân tách các gói JavaScript và chỉ tải trước các đoạn quan trọng.

Cách triển khai rel=preload

Cách đơn giản nhất để triển khai preload là thêm thẻ <link> vào <head> của tài liệu:

<head>
  <link rel="preload" as="script" href="critical.js">
</head>

Việc cung cấp thuộc tính as giúp trình duyệt đặt mức độ ưu tiên của tài nguyên được tìm nạp trước theo loại tài nguyên, đặt đúng tiêu đề và xác định xem tài nguyên đó đã tồn tại trong bộ nhớ đệm hay chưa. Các giá trị được chấp nhận cho thuộc tính này bao gồm: script, style, font, imageothers (khác).

Một số loại tài nguyên, chẳng hạn như phông chữ, được tải ở chế độ ẩn danh. Đối với những thuộc tính đó, bạn phải đặt thuộc tính crossorigin bằng preload:

<link rel="preload" href="ComicSans.woff2" as="font" type="font/woff2" crossorigin>

Phần tử <link> cũng chấp nhận thuộc tính type, chứa loại MIME của tài nguyên được liên kết. Trình duyệt sử dụng giá trị của thuộc tính type để đảm bảo rằng các tài nguyên chỉ được tải trước nếu loại tệp của tài nguyên đó được hỗ trợ. Nếu không hỗ trợ loại tài nguyên đã chỉ định, trình duyệt sẽ bỏ qua <link rel="preload">.

Bạn cũng có thể tải trước mọi loại tài nguyên thông qua tiêu đề HTTP Link:

Link: </css/style.css>; rel="preload"; as="style"

Lợi ích của việc chỉ định preload trong Tiêu đề HTTP là trình duyệt không cần phân tích cú pháp tài liệu để khám phá tài liệu đó, điều này có thể mang lại một số điểm cải tiến nhỏ trong một số trường hợp.

Tải trước các mô-đun JavaScript bằng webpack

Nếu đang sử dụng trình tạo gói mô-đun tạo tệp bản dựng của ứng dụng, bạn cần kiểm tra xem trình tạo gói đó có hỗ trợ chèn thẻ tải trước hay không. Với webpack phiên bản 4.6.0 trở lên, tính năng tải trước được hỗ trợ thông qua việc sử dụng nhận xét ma thuật bên trong import():

import(_/* webpackPreload: true */_ "CriticalChunk")

Nếu bạn đang sử dụng phiên bản webpack cũ, hãy sử dụng trình bổ trợ của bên thứ ba như preload-webpack-plugin.

Ảnh hưởng của tính năng tải trước đối với Các chỉ số quan trọng về trang web

Tải trước là một tính năng tối ưu hoá hiệu suất mạnh mẽ có ảnh hưởng đến tốc độ tải. Những hoạt động tối ưu hoá như vậy có thể dẫn đến thay đổi trong Chỉ số quan trọng chính của trang web của trang web. Bạn cần lưu ý đến những thay đổi này.

Thời gian hiển thị nội dung lớn nhất (LCP)

Tính năng tải trước có tác động mạnh mẽ đến Thời gian hiển thị nội dung lớn nhất (LCP) đối với phông chữ và hình ảnh, vì cả hình ảnh và nút văn bản đều có thể là ứng viên LCP. Hình ảnh chính và các dòng văn bản lớn được kết xuất bằng phông chữ web có thể hưởng lợi đáng kể từ gợi ý tải trước được đặt đúng chỗ và nên được sử dụng khi có cơ hội phân phối những nội dung quan trọng này cho người dùng nhanh hơn.

Tuy nhiên, bạn cần cẩn thận khi tải trước và tối ưu hoá các tính năng khác! Cụ thể, hãy tránh tải trước quá nhiều tài nguyên. Nếu bạn ưu tiên quá nhiều tài nguyên, thì không có tài nguyên nào được ưu tiên hiệu quả. Tác động của các gợi ý tải trước quá mức sẽ đặc biệt gây hại cho những người dùng trên mạng chậm hơn, nơi tranh chấp băng thông sẽ rõ ràng hơn.

Thay vào đó, hãy tập trung vào một vài tài nguyên có giá trị cao mà bạn biết sẽ được hưởng lợi từ việc tải trước được đặt đúng cách. Khi tải phông chữ trước, hãy đảm bảo rằng bạn đang phân phát phông chữ ở định dạng WOFF 2.0 để giảm thời gian tải tài nguyên càng nhiều càng tốt. Vì WOFF 2.0 có khả năng hỗ trợ trình duyệt tuyệt vời, nên việc sử dụng các định dạng cũ như WOFF 1.0 hoặc TrueType (TTF) sẽ làm chậm LCP nếu đề xuất LCP là một nút văn bản.

Đối với LCP và JavaScript, bạn cần đảm bảo rằng bạn đang gửi đầy đủ mã đánh dấu từ máy chủ để trình quét tải trước của trình duyệt hoạt động đúng cách. Nếu bạn đang phân phát một trải nghiệm hoàn toàn dựa vào JavaScript để hiển thị mã đánh dấu và không thể gửi HTML do máy chủ hiển thị, thì bạn nên can thiệp vào những nơi mà trình quét tải trước của trình duyệt không thể và tải trước các tài nguyên chỉ có thể được phát hiện khi JavaScript tải xong và thực thi.

Điểm số tổng hợp về mức thay đổi bố cục (CLS)

Sự thay đổi bố cục tích luỹ (CLS) là một chỉ số đặc biệt quan trọng liên quan đến phông chữ web. CLS có sự tương tác đáng kể với phông chữ web sử dụng thuộc tính CSS font-display để quản lý cách tải phông chữ. Để giảm thiểu sự thay đổi bố cục liên quan đến phông chữ web, hãy cân nhắc các chiến lược sau:

  1. Tải trước phông chữ trong khi sử dụng giá trị block mặc định cho font-display. Đây là một sự cân bằng tinh tế. Việc chặn hiển thị phông chữ mà không có phông chữ dự phòng có thể được coi là vấn đề về trải nghiệm người dùng. Mặt khác, việc tải phông chữ bằng font-display: block; sẽ loại bỏ các thay đổi bố cục liên quan đến phông chữ web. Mặt khác, bạn vẫn muốn tải các phông chữ web đó càng sớm càng tốt nếu chúng đóng vai trò quan trọng đối với trải nghiệm người dùng. Bạn có thể kết hợp tính năng tải trước với font-display: block; để có được một giải pháp dung hoà chấp nhận được.
  2. Tải trước phông chữ trong khi sử dụng giá trị fallback cho font-display. fallback là một giải pháp trung gian giữa swapblock, trong đó có một khoảng thời gian chặn cực ngắn.
  3. Sử dụng giá trị optional cho font-display mà không cần tải trước. Nếu phông chữ web không quan trọng đối với trải nghiệm người dùng nhưng vẫn được dùng để hiển thị một lượng lớn văn bản trên trang, hãy cân nhắc sử dụng giá trị optional. Trong điều kiện bất lợi, optional sẽ hiển thị văn bản trang bằng phông chữ dự phòng trong khi tải phông chữ ở chế độ nền cho thao tác điều hướng tiếp theo. Kết quả cuối cùng trong những điều kiện này là CLS được cải thiện, vì phông chữ hệ thống sẽ hiển thị ngay lập tức, trong khi các lần tải trang tiếp theo sẽ tải phông chữ ngay lập tức mà không có sự thay đổi bố cục.

CLS là một chỉ số khó tối ưu hoá khi nói đến phông chữ web. Như mọi khi, hãy thử nghiệm trong phòng thí nghiệm, nhưng hãy tin tưởng dữ liệu thực địa để xác định xem chiến lược tải phông chữ của bạn có cải thiện CLS hay khiến CLS trở nên tệ hơn.

Lượt tương tác đến nội dung hiển thị tiếp theo (INP)

Lượt tương tác đến nội dung hiển thị tiếp theo là chỉ số đo lường khả năng phản hồi đối với hoạt động đầu vào của người dùng. Vì phần lớn khả năng tương tác trên web là do JavaScript cung cấp, nên việc tải trước JavaScript hỗ trợ các hoạt động tương tác quan trọng có thể giúp giảm INP của trang. Tuy nhiên, hãy lưu ý rằng việc tải trước quá nhiều JavaScript trong quá trình khởi động có thể gây ra những hậu quả tiêu cực ngoài mong muốn nếu có quá nhiều tài nguyên đang tranh giành băng thông.

Bạn cũng cần cẩn thận về cách phân tách mã. Tính năng phân tách mã là một tính năng tối ưu hoá tuyệt vời để giảm lượng JavaScript được tải trong quá trình khởi động, nhưng các lượt tương tác có thể bị trì hoãn nếu chúng dựa vào JavaScript được tải ngay từ đầu lượt tương tác. Để bù đắp cho điều này, bạn cần kiểm tra ý định của người dùng và chèn một tệp tải trước cho(các) đoạn JavaScript cần thiết trước khi tương tác diễn ra. Ví dụ: tải trước JavaScript cần thiết để xác thực nội dung của biểu mẫu khi bất kỳ trường nào trong biểu mẫu được lấy tiêu điểm.

Kết luận

Để cải thiện tốc độ trang, hãy tải trước các tài nguyên quan trọng mà trình duyệt phát hiện muộn. Việc tải trước mọi thứ sẽ phản tác dụng, vì vậy, hãy sử dụng preload một cách tiết kiệm và đo lường tác động trong thế giới thực.