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áy chủ, phân tích cú pháp nội dung của trang web 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 về tất cả tài nguyên mà trang của mình cần và tài nguyên nào trong số đó là 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 đạt được điều đó bằng <link rel="preload">.

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

Tính năng tải trước phù hợp nhất với các tài nguyên mà trình duyệt thường 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 cho trình duyệt biết rằng bạn muốn tìm nạp tài nguyên này sớm hơn so với khả năng trình duyệt phát hiện ra vì bạn chắc chắn rằng tài nguyên này quan trọng đối với trang hiện tại.

Ảnh chụp màn hình của 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 nên quá trình tải xuống diễn ra song song với biểu định 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.

Kiểm tra các 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> chứa rel="preload" vào phần đầ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 để chúng có sẵn ngay lập tức 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.)

Gợi ý về tài nguyên (ví dụ: preconnectprefetch) sẽ đượ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 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 chèn vào cùng dòng 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 thiết lập mức độ ưu tiên của tài nguyên được tìm nạp trước theo loại, đặt tiêu đề phù hợp 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 thẻ đó, 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>

Các 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. Các trình duyệt sử dụng giá trị của thuộc tính type để đảm bảo 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 có quá nhiều tài nguyên được ưu tiên, thì thực tế là không có tài nguyên nào trong số đó được ưu tiên. 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 số tài nguyên có giá trị cao mà bạn biết rằng việc tải trước được đặt đúng vị trí. Khi tải trước phông chữ, hãy đảm bảo rằng bạn đang phân phối phông chữ ở định dạng WOFF 2.0 để giảm thời gian tải tài nguyên nhiều nhất có thể. 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 đang cung cấp trải nghiệm hoàn toàn dựa vào JavaScript để hiển thị đánh dấu và không thể gửi HTML do máy chủ kết xuất, bạn nên thực hiện bước vào trường hợp trình duyệt không thể tải trước trình quét và tải trước các tài nguyên mà chỉ có thể phát hiện được khi JavaScript hoàn tất tải 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à 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 mặt, 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. Việc kết hợp một lượt tải trước với font-display: block; có thể là sự kết hợp 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à sự hoà hợp giữa swapblock, trong đó nó có 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ữ trên 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 đáng kể 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 (Mức thay đổi bố cục tích luỹ) là một chỉ số khó tối ưu hoá khi xét đến phông chữ trên 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 làm 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 với Next Paint 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 mang lại, 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 khi 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ã. Chia tách mã là một phương pháp tối ưu hoá rất hiệu quả để giảm lượng JavaScript được tải trong quá trình khởi động, nhưng các hoạt động tương tác có thể bị trì hoãn nếu chúng dựa vào JavaScript được tải ngay khi bắt đầu tương tác. Để khắc phục vấn đề 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 làm 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.