Tìm nạp trước, kết xuất trước và lưu trước trình chạy dịch vụ

Trong một vài mô-đun gần đây, bạn đã khám phá các khái niệm như hoãn tải JavaScripttải từng phần hình ảnh và các phần tử <iframe>. Việc trì hoãn tải tài nguyên sẽ giảm mức sử dụng mạng và CPU trong quá trình tải trang ban đầu bằng cách tải tài nguyên xuống tại thời điểm cần thiết, thay vì tải trước các tài nguyên đó, vì có thể các tài nguyên này sẽ không được sử dụng. Điều này có thể cải thiện thời gian tải trang ban đầu, nhưng các lượt tương tác tiếp theo có thể bị chậm trễ nếu các tài nguyên cần thiết để hỗ trợ các lượt tương tác đó chưa được tải tại thời điểm chúng xảy ra.

Ví dụ: nếu một trang chứa bộ chọn ngày tuỳ chỉnh, bạn có thể hoãn tài nguyên của bộ chọn ngày cho đến khi người dùng tương tác với phần tử. Tuy nhiên, việc tải các tài nguyên của bộ chọn ngày theo yêu cầu có thể dẫn đến sự chậm trễ (có thể là một chút, nhưng cũng có thể không, tuỳ thuộc vào kết nối mạng, khả năng của thiết bị hoặc cả hai của người dùng) cho đến khi các tài nguyên được tải xuống, phân tích cú pháp và có sẵn để thực thi.

Đây là một sự cân bằng khá khó khăn – bạn không muốn lãng phí băng thông bằng cách tải các tài nguyên có thể không được dùng, nhưng việc trì hoãn các lượt tương tác và các lượt tải trang tiếp theo cũng không phải là lựa chọn lý tưởng. Rất may là có một số công cụ mà bạn có thể dùng để cân bằng tốt hơn giữa hai thái cực này. Mô-đun này đề cập đến một số kỹ thuật mà bạn có thể dùng để đạt được mục tiêu đó, chẳng hạn như tìm nạp trước tài nguyên, kết xuất trước toàn bộ trang và lưu trước tài nguyên vào bộ nhớ đệm bằng trình chạy dịch vụ.

Tìm nạp trước các tài nguyên cần thiết trong tương lai gần ở mức độ ưu tiên thấp

Bạn có thể tìm nạp trước tài nguyên (bao gồm cả hình ảnh, biểu định kiểu hoặc tài nguyên JavaScript) bằng cách sử dụng gợi ý về tài nguyên <link rel="prefetch">. Gợi ý prefetch cho trình duyệt biết rằng một tài nguyên có thể sẽ cần thiết trong tương lai gần.

Khi bạn chỉ định một gợi ý prefetch, trình duyệt có thể bắt đầu một yêu cầu cho tài nguyên đó ở mức độ ưu tiên thấp nhất để tránh tranh chấp với các tài nguyên cần thiết cho trang hiện tại.

Việc tìm nạp trước tài nguyên có thể cải thiện trải nghiệm người dùng, vì người dùng không cần phải đợi tải xuống các tài nguyên cần thiết trong tương lai gần, vì họ có thể truy xuất ngay các tài nguyên đó từ bộ nhớ đệm trên đĩa tại thời điểm cần.

<head>
  <!-- ... -->
  <link rel="prefetch" as="script" href="/date-picker.js">
  <link rel="prefetch" as="style" href="/date-picker.css">
  <!-- ... -->
</head>

Đoạn mã HTML trước đó thông báo cho trình duyệt rằng trình duyệt có thể tìm nạp trước date-picker.jsdate-picker.css khi không hoạt động. Bạn cũng có thể tìm nạp trước các tài nguyên một cách linh động khi người dùng tương tác với trang bằng JavaScript.

prefetch được hỗ trợ trên tất cả các trình duyệt hiện đại, ngoại trừ Safari. Trong Safari, prefetch có sẵn sau một cờ. Nếu bạn thực sự cần tải trước các tài nguyên cho trang web của mình theo cách hoạt động trên tất cả trình duyệt và bạn đang sử dụng một worker dịch vụ, hãy đọc phần sau trong mô-đun này về tài nguyên lưu vào bộ nhớ đệm trước bằng worker dịch vụ.

Tìm nạp trước các trang để tăng tốc độ điều hướng trong tương lai

Bạn cũng có thể tìm nạp trước một trang và tất cả các tài nguyên phụ của trang đó bằng cách chỉ định thuộc tính as="document" khi trỏ đến một tài liệu HTML:

<link rel="prefetch" href="/page" as="document">

Khi không hoạt động, trình duyệt có thể bắt đầu một yêu cầu có mức độ ưu tiên thấp cho /page.

Trong các trình duyệt dựa trên Chromium, bạn có thể tìm nạp trước các tài liệu bằng cách sử dụng Speculation Rules API. Quy tắc suy đoán được xác định là một đối tượng JSON có trong HTML của trang hoặc được thêm động thông qua JavaScript:

<script type="speculationrules">
{
  "prefetch": [{
    "source": "list",
    "urls": ["/page-a", "/page-b"]
  }]
}
</script>

Đối tượng JSON mô tả một hoặc nhiều hành động (hiện chỉ hỗ trợ prefetchprerender) và danh sách URL được liên kết với hành động đó. Trong đoạn mã HTML trước đó, trình duyệt được hướng dẫn tìm nạp trước /page-a/page-b. Tương tự như <link rel="prefetch">, quy tắc suy đoán là một gợi ý mà trình duyệt có thể bỏ qua trong một số trường hợp nhất định.

Các thư viện như Quicklink cải thiện hoạt động điều hướng trang bằng cách tự động tìm nạp trước hoặc kết xuất trước các đường liên kết đến các trang sau khi chúng xuất hiện trong khung hiển thị của người dùng. Điều này làm tăng khả năng người dùng cuối cùng sẽ chuyển đến trang đó so với việc tìm nạp trước tất cả các đường liên kết trên trang.

Kết xuất trước các trang

Ngoài việc tìm nạp trước các tài nguyên, bạn cũng có thể gợi ý cho trình duyệt kết xuất trước một trang trước khi người dùng chuyển đến trang đó. Việc này có thể giúp tải trang gần như tức thì, vì trang và tài nguyên của trang được tìm nạp và xử lý ở chế độ nền. Sau khi người dùng chuyển đến trang, trang đó sẽ được đặt ở nền trước.

Tính năng kết xuất trước được hỗ trợ thông qua Speculation Rules API:

<script type="speculationrules">
{
  "prerender": [
    {
      "source": "list",
      "urls": ["/page-a", "page-b"]
    }
  ]
}
</script>

Bản minh hoạ tìm nạp trước và kết xuất trước

Lưu trước vào bộ nhớ đệm của trình chạy dịch vụ

Bạn cũng có thể tìm nạp trước tài nguyên một cách suy đoán bằng cách sử dụng trình chạy dịch vụ. Tính năng lưu trước vào bộ nhớ đệm của worker dịch vụ có thể tìm nạp và lưu tài nguyên bằng Cache API, cho phép trình duyệt phân phát yêu cầu bằng Cache API mà không cần truy cập vào mạng. Tính năng lưu vào bộ nhớ đệm trước của worker dịch vụ sử dụng một chiến lược lưu vào bộ nhớ đệm của worker dịch vụ rất hiệu quả, được gọi là chiến lược chỉ lưu vào bộ nhớ đệm. Mẫu này rất hiệu quả vì sau khi được đặt vào bộ nhớ đệm của worker dịch vụ, các tài nguyên sẽ được tìm nạp gần như ngay lập tức theo yêu cầu.

Cho thấy quy trình lưu vào bộ nhớ đệm của trình chạy dịch vụ từ trang, đến trình chạy dịch vụ, đến bộ nhớ đệm.
Chiến lược chỉ dùng bộ nhớ đệm chỉ truy xuất các tài nguyên đủ điều kiện từ mạng trong quá trình cài đặt trình chạy dịch vụ. Sau khi cài đặt, các tài nguyên được lưu vào bộ nhớ đệm sẽ chỉ được truy xuất từ bộ nhớ đệm của worker dịch vụ.

Để lưu trước các tài nguyên vào bộ nhớ đệm bằng trình chạy dịch vụ, bạn có thể sử dụng Workbox. Tuy nhiên, nếu muốn, bạn có thể viết mã của riêng mình để lưu vào bộ nhớ đệm một nhóm tệp được xác định trước. Dù bạn quyết định sử dụng service worker để lưu trước tài nguyên vào bộ nhớ đệm theo cách nào, bạn cũng cần biết rằng quá trình lưu trước vào bộ nhớ đệm sẽ diễn ra khi service worker được cài đặt. Sau khi cài đặt, các tài nguyên được lưu vào bộ nhớ đệm trước sẽ có sẵn để truy xuất trên mọi trang mà trình chạy dịch vụ kiểm soát trên trang web của bạn.

Workbox sử dụng một tệp kê khai lưu vào bộ nhớ đệm trước để xác định những tài nguyên cần được lưu vào bộ nhớ đệm trước. Tệp kê khai lưu vào bộ nhớ đệm trước là một danh sách các tệp và thông tin về phiên bản đóng vai trò là "nguồn dữ liệu chính xác nhất" cho các tài nguyên cần được lưu vào bộ nhớ đệm trước.

[{  
    url: 'script.ffaa4455.js',
    revision: null
}, {
    url: '/index.html',
    revision: '518747aa'
}]

Đoạn mã trên là một ví dụ về tệp kê khai bao gồm 2 tệp: script.ffaa4455.js/index.html. Nếu một tài nguyên chứa thông tin phiên bản trong chính tệp đó (còn gọi là hàm băm tệp), thì bạn có thể để thuộc tính revisionnull vì tệp đã được tạo phiên bản (ví dụ: ffaa4455 cho tài nguyên script.ffaa4455.js trong mã trước đó). Đối với các tài nguyên chưa được gắn phiên bản, bạn có thể tạo một bản sửa đổi cho các tài nguyên đó tại thời điểm tạo bản dựng.

Sau khi thiết lập, bạn có thể dùng trình chạy dịch vụ để lưu trước vào bộ nhớ đệm các trang tĩnh hoặc tài nguyên phụ của các trang đó nhằm tăng tốc độ điều hướng trang sau này.

workbox.precaching.precacheAndRoute([
  '/styles/product-page.ac29.css',
  '/styles/product-page.39a1.js',
]);

Ví dụ: trên trang thông tin sản phẩm của trang web thương mại điện tử, bạn có thể dùng một worker dịch vụ để lưu trước vào bộ nhớ đệm CSS và JavaScript cần thiết để hiển thị trang chi tiết sản phẩm, giúp người dùng cảm thấy thao tác chuyển đến trang chi tiết sản phẩm diễn ra nhanh hơn nhiều. Trong ví dụ trước, product-page.ac29.cssproduct-page.39a1.js được lưu trước vào bộ nhớ đệm. Phương thức precacheAndRoute có trong workbox-precaching sẽ tự động đăng ký các trình xử lý cần thiết để đảm bảo các tài nguyên được lưu vào bộ nhớ đệm trước được tìm nạp từ API trình chạy dịch vụ bất cứ khi nào cần.

service worker được hỗ trợ rộng rãi, nên bạn có thể sử dụng tính năng lưu trước vào bộ nhớ đệm của service worker trên mọi trình duyệt hiện đại khi cần.

Kiểm tra kiến thức của bạn

Gợi ý prefetch xuất hiện ở mức độ ưu tiên nào?

Thấp.
Cao.
Trung bình.

Sự khác biệt giữa việc tìm nạp trước và kết xuất trước một trang là gì?

Chúng hầu hết đều giống nhau, chỉ có điều hoạt động kết xuất trước sẽ nhận được tất cả các tài nguyên phụ của một trang, còn hoạt động tìm nạp trước thì không.
Mặc dù cả hoạt động tìm nạp trước và kết xuất trước cho một trang đều nhận được một trang và tất cả các tài nguyên phụ của trang đó, nhưng hoạt động tìm nạp trước chỉ truy xuất trang và tất cả các tài nguyên của trang đó, trong khi hoạt động kết xuất trước tiến thêm một bước bằng cách kết xuất toàn bộ trang ở chế độ nền cho đến khi người dùng chuyển đến trang đó.

Bộ nhớ đệm của worker dịch vụ và bộ nhớ đệm HTTP là như nhau.

Sai
Đúng

Tiếp theo: Tổng quan về web worker

Giờ đây, bạn đã biết được lợi ích của việc tìm nạp trước, kết xuất trước và lưu vào bộ nhớ đệm trước bằng trình chạy dịch vụ khi tăng tốc độ điều hướng đến các trang trong tương lai. Nhờ đó, bạn có thể đưa ra một số quyết định sáng suốt về cách thức mang lại lợi ích cho trang web và người dùng của trang web.

Tiếp theo, thông tin tổng quan về web worker sẽ được cung cấp, cũng như cách các web worker này có thể loại bỏ những công việc tốn kém khỏi luồng chính và giúp luồng chính có thêm thời gian để xử lý các hoạt động tương tác của người dùng. Nếu bạn từng thắc mắc về những việc có thể làm để giúp luồng chính có thêm khoảng trống, thì 2 mô-đun tiếp theo rất đáng để bạn dành thời gian tìm hiểu!