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 đó và gửi yêu cầu riêng cho bất kỳ tài nguyên được tham chiếu nào. 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 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ùy chọn tải trước phù hợp nhất với các tài nguyên thường bị 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 của 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 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 đó sớm hơn trình duyệt sẽ phát hiệ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 quy trình 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 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 tài sản ở cấp thứ ba của chuỗi này đượ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 những tài nguyên cần tải trước.

Kiểm tra các yêu cầu chính 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 phần đầu của 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 tải trước vào bộ nhớ đệm để 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, ví dụ như 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á hiệu quả trong việc ưu tiên các tài nguyên. Do đó, bạn cần sử dụng preload một cách hạn chế và chỉ tải trước những tài nguyên quan trọng nhất.

Các lượt tải trước không sử dụng 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ề các tài nguyên 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 sẽ không phát hiện 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ệp CSS được tải xuống.

Tải trước tệp CSS

Nếu đang sử dụng phương pháp tiếp cận quan trọng về CSS, thì bạn sẽ 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 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ì các 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 riêng việc tìm nạp khỏi quá trình thực thi, từ đó 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 của mình 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 đặt 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 trường hợp đó, 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 có 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 chúng được hỗ trợ. Nếu trình duyệt 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 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ể cung cấp 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 đóng 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 chương trình này có hỗ trợ tính năng chèn thẻ tải trước hay không. Với webpack 4.6.0 trở lên, bạn có thể tải trước thông qua việc sử dụng bình luận ma thuật bên trong import():

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

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

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

Tải trước là một cách tối ưu hoá hiệu suất mạnh mẽ có ảnh hưởng đến tốc độ tải. Những cách 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 phải nắm rõ những thay đổi này.

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

Quá trình 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à đề xuất LCP. Hình ảnh chính và các loạt văn bản lớn được hiển thị 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 cung cấp 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 phải thận trọng khi 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 có quá nhiều tài nguyên được ưu tiên, thì sẽ không có tài nguyên nào được ưu tiên. Ảnh hưởng của các gợi ý tải trước quá mức sẽ đặc biệt bất lợi đối với những gợi ý trên các mạng chậm hơn, nơi mà sự 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 sẽ được hưởng lợi từ việc tải trước được đặt đúng 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 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 ứng viên LCP là nút văn bản.

Khi nói đến LCP và JavaScript, bạn cần đảm bảo rằng bạn đang gửi hoàn chỉnh 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 bình thường. Nếu đang cung cấp 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ủ kết xuất, thì bạn nên chuyển sang nơi 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à lẽ ra chỉ có thể tìm thấy khi JavaScript hoàn tất việc tải và thực thi.

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

Điểm số tổng hợp về mức thay đổi bố cục (CLS) là một chỉ số đặc biệt quan trọng đối với phông chữ trên web, và CLS có tác động đáng kể đến những 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 về 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 sử dụng giá trị block mặc định cho font-display. Đây là sự cân bằng mong manh. Việc chặn hiển thị phông chữ mà không có tính năng 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; giúp loại bỏ những thay đổi về 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 quan trọng đối với trải nghiệm người dùng. Bạn có thể chấp nhận việc kết hợp tải trước với font-display: block;.
  2. Tải trước phông chữ trong khi sử dụng giá trị fallback cho font-display. fallback là thoả thuận giữa swapblock, trong đó có khoảng thời gian chặn cực kỳ 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 các đ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ữ trong 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ần 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 các chiến lược tải phông chữ của bạn có giúp cải thiện CLS hay làm cho tình hình trở nên kém hiệu quả 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 Nội dung hiển thị tiếp theo là chỉ số đánh giá khả năng thích ứng với hoạt động đầu vào của người dùng. Vì thị phần tương tác trên web chủ yếu được thúc đẩy bởi JavaScript, 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ữ cho INP của trang thấp hơn. 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ể dẫn đến hậu quả tiêu cực ngoài ý 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 cẩn thận về cách chia tách mã. Tách mã là một biện pháp tối ưu hoá hiệu quả để giảm số 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 khi bắt đầu 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 tải 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à 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 tập trung.

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.