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à một nhà phát triển, bạn đã biết về tất cả các tài nguyên mà trang của bạn 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 thời hạn 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ải trước phù hợp nhất với những tài nguyên mà trình duyệt thường phát hiện muộn.

Ảnh chụp màn hình của 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 biểu đị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 trang định kiểu xong.

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 thời điểm trình duyệt có thể phát hiện ra tài nguyên đó, vì bạn chắc chắn rằng tài nguyên đó 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 của Công cụ của Chrome cho nhà phát triển 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ủa các tài nguyên được trình duyệt ưu tiên và tìm nạp. Lighthouse xác định những thành phần ở cấp thứ ba của chuỗi này là thành phần được phát hiện muộn. Bạn có thể sử dụng chế độ kiểm tra Tải trước các yêu cầu chính để xác định những tài nguyên cần tải trước.

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

Bạn có thể tải trước cá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 vào bộ nhớ đệm các tài nguyên được tải trước để chúng có sẵn ngay khi cần. (Thao tác này không thực thi tập lệnh hoặc áp dụng biểu định kiểu.)

Các gợi ý về tài nguyên, chẳng hạn như 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á giỏi trong việc ưu tiên tài nguyên. Đó là lý do tại sao bạn nên sử dụng preload một cách hợp lý và chỉ tải trước những tài nguyên quan trọng nhất.

Các hoạt động tải trước không dùng đến sẽ kích hoạt cảnh báo 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ề các tài nguyên được tải trước nhưng không 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

Các 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á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 các tệp CSS được tải xuống.

Tải trước cá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 2 phần. CSS quan trọng cần thiết để kết xuất nội dung trong màn hình đầu tiên được chèn vào <head> của tài liệu và CSS không quan trọng thường được tải từng phần 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 sự chậm 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 cá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 việc tải trước rất hữu ích để tách quá trình tìm nạp khỏi quá trình thực thi. Điều này có thể cải thiện các chỉ số như Thời gian tương tác. 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 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, imagecác giá trị 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 này, 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 một 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 rằng 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"

Một 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 để phát hiện ra tiêu đề này, điều này có thể mang lại một số 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 một trình đóng gói mô-đun tạo các tệp bản dựng của ứng dụng, bạn cần kiểm tra xem trình đóng gói đó có hỗ trợ việc 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 đặc biệ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 dùng một trình bổ trợ của bên thứ ba như preload-webpack-plugin.

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

Tải trước là một phương pháp tối ưu hoá hiệu suất hiệu quả, 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 những thay đổi về Chỉ số quan trọng chính của trang web. Vì vậy, 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)

Việc tải trước có ảnh hưởng lớn đế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à LCP candidate (đối tượng LCP). Hình ảnh chính và các đoạn văn bản lớn được kết xuất bằng phông chữ trên web có thể hưởng lợi đáng kể từ một gợi ý tải trước được đặt đúng vị trí và nên được sử dụng khi có cơ hội phân phối những phần 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 nói đến việc tải trước và các hoạt động tối ưu hoá 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ì thực tế là không có tài nguyên nào được ưu tiên. Tác động của quá nhiều gợi ý tải trước sẽ đặc biệt gây bất lợi cho những người dùng mạng chậm, nơi tình trạng 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 sẽ được hưởng lợi từ một hoạt động 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át 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ũ hơn như WOFF 1.0 hoặc TrueType (TTF) sẽ làm chậm LCP nếu thành phần 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 mã đánh dấu hoàn chỉnh 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 để kết xuất mã đánh dấu và không thể gửi HTML được kết xuất phía máy chủ, thì bạn nên can thiệp vào nơi 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 mà nếu không thì chỉ có thể phát hiện được khi JavaScript tải và thực thi xong.

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

Độ trễ 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 và 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 các thay đổi về bố cục liên quan đến phông chữ trên 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à một 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ữ trên web. Mặt khác, bạn vẫn muốn tải những phông chữ trên 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. Kết hợp một hoạt động tải trước với font-display: block; có thể là một giải pháp thoả hiệ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à một giải pháp thoả hiệp giữa swapblock, vì nó có 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 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 trên trang bằng một phông chữ dự phòng trong khi tải phông chữ ở chế độ nền cho lần đ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ữ trên web. Như thường lệ, hãy thử nghiệm trong phòng thí nghiệm, nhưng hãy tin tưởng dữ liệu thực tế để xác định xem chiến lược tải phông chữ của bạn có cải thiện CLS hay không.

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à một 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 tính tương tác trên web được điều khiển bằng JavaScript, 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 chỉ số 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 hậu quả tiêu cực ngoài ý muốn nếu có quá nhiều tài nguyên tranh giành băng thông.

Bạn cũng cần cẩn thận về cách thực hiện phân chia mã. Phân chia mã là một phương pháp 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 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 hoạt động tương tác. Để bù đắp cho điều này, bạn cần phải kiểm tra ý định của người dùng và chèn một lệnh tải trước cho(các) đoạn JavaScript cần thiết trước khi hoạt động tương tác diễn ra. Một ví dụ có thể là 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 được 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.