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ể vận dụng kiến thức đó để yêu cầu trước các tài nguyên quan trọng 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 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 xong và phân tích cú pháp biểu đị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 bảng điều khiển Mạng Chrome Công cụ cho nhà phát triển sau khi áp dụ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ự tài nguyên mà trình duyệt ưu tiên và tìm nạp. Lighthouse xác định các tài sản ở cấp thứ ba trong chuỗi này là 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 những 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 khi cần. (Tệp này không thực thi tập lệnh hoặc áp dụng biểu định kiểu.)

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 vốn đã khá hiệu quả trong việc ưu tiên tài nguyên. Đó là lý do bạn nên sử dụng preload một cách thận trọng và chỉ tải trước các tài nguyên quan trọng nhất.

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

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

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

Hệ thống không phát hiện được 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 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 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 đã chia CSS của mình 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 nằm trong <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 hiển thị 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ì các trình duyệt không thực thi các tệp tải trước, nên tính năng tải trước rất hữu ích khi tách biệt hoạt động tìm nạp với quá trình thực thi, nhờ đó 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 phần quan trọng.

Cách triển khai rel=preview

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, 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 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 trình duyệt không hỗ trợ loại tài nguyên được chỉ định thì trình duyệt sẽ bỏ qua <link rel="preload">.

Bạn cũng có thể tải trước bất kỳ loại tài nguyên nào 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 những cải tiến nhỏ trong một số trường hợp.

Tải trước mô-đun JavaScript bằng gói web

Nếu đang sử dụng trình gói mô-đun giúp 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 này có hỗ trợ tính năng 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ợ bằng cách sử dụng chú thích kỳ diệu trong import():

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

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

Ảnh hưởng của việc tải trước Core Web Vitals

Tải trước là 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 những thay đổi đối với Các chỉ số quan trọng về trang web của trang web. Bạn cần nắm rõ 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 Nội dung lớn nhất hiển thị (LCP) khi nói đến 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à đoạn văn bản lớn hiển thị bằng phông chữ trên web có thể hưởng lợi đáng kể từ gợi ý tải trước được đặt ở vị trí phù hợp. Bạn nên sử dụng gợi ý này khi có cơ hội phân phối các đoạn nội dung quan trọng này cho người dùng nhanh hơn.

Tuy nhiên, bạn nên cẩn thận khi tải trước và các biện pháp tối ưu hoá khác! Cụ thể, bạn nên 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 quá nhiều gợi ý tải trước sẽ đặc biệt bất lợi đối với những 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 cách. 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ó hỗ trợ trình duyệt rất tốt, nên việc sử dụng các định dạng cũ như WOFF 1.0 hoặc TrueType (TTF) sẽ trì hoãn LCP của bạn nếu ứng viên LCP là một nút văn bản.

Khi nói đến LCP và JavaScript, bạn nê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 đ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)

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

  1. Tải trước phông chữ trong khi vẫn 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ó dự phòng có thể được xem 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ỏ sự thay đổi bố cục liên quan đến phông chữ trên web. Mặt khác, bạn vẫn nên tải các phông chữ đó trên web càng sớm càng tốt nếu chúng có 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à một cách 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ự thoả hiệ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 các điều kiện này sẽ giúp cải thiện CLS, vì phông chữ hệ thống sẽ hiển thị ngay lập tức, trong khi các lượt tải trang tiếp theo sẽ tải phông chữ ngay lập tức mà không cần thay đổi bố cục.

CLS là một chỉ số khó tối ưu hoá khi xét đế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ế tại chỗ để xác định xem chiến lược tải phông chữ của bạn đang cải thiện CLS (Mức thay đổi bố cục tích luỹ) hay làm cho mức này kém đi.

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ì tỷ lệ tương tác chủ yếu trên web là do JavaScript chi phối, nên việc tải trước JavaScript hỗ trợ các tương tác quan trọng có thể giúp giảm INP của trang. Tuy nhiên, xin lưu ý rằng việc tải trước quá nhiều JavaScript trong quá trình khởi động có thể dẫn đến những hậu quả tiêu cực không mong muốn nếu có quá nhiều tài nguyên đang cạnh tranh về băng thông.

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