Bộ nhớ đệm là một công cụ mạnh mẽ. Điều này giúp ứng dụng của bạn ít phụ thuộc vào điều kiện mạng hơn. Bằng cách sử dụng bộ nhớ đệm một cách hiệu quả, bạn có thể cung cấp ứng dụng web khi không có mạng và phân phát các thành phần nhanh nhất có thể trong mọi điều kiện mạng. Như đã đề cập trong phần Thành phần và dữ liệu, bạn có thể quyết định chiến lược tốt nhất để lưu các thành phần cần thiết vào bộ nhớ đệm. Để quản lý bộ nhớ đệm, worker của dịch vụ sẽ tương tác với API bộ nhớ đệm.
Bạn có thể sử dụng API Bộ nhớ đệm từ nhiều ngữ cảnh:
- Ngữ cảnh cửa sổ (luồng chính của PWA).
- Trình chạy dịch vụ.
- Mọi worker khác mà bạn sử dụng.
Một lợi thế của việc quản lý bộ nhớ đệm bằng trình chạy dịch vụ là vòng đời của bộ nhớ đệm không liên kết với cửa sổ, tức là bạn không chặn luồng chính. Xin lưu ý rằng để sử dụng API Lưu trữ bộ nhớ đệm, hầu hết các ngữ cảnh này phải nằm trong kết nối TLS.
Nội dung cần lưu vào bộ nhớ đệm
Câu hỏi đầu tiên bạn có thể đặt ra về việc lưu vào bộ nhớ đệm là nội dung cần lưu vào bộ nhớ đệm. Mặc dù không có câu trả lời duy nhất cho câu hỏi đó, nhưng bạn có thể bắt đầu bằng tất cả tài nguyên tối thiểu cần thiết để hiển thị giao diện người dùng.
Những tài nguyên đó phải bao gồm:
- HTML trang chính (start_url của ứng dụng).
- Các tệp phông chữ CSS cần thiết cho giao diện người dùng chính.
- Hình ảnh dùng trong giao diện người dùng.
- Các tệp JavaScript cần thiết để hiển thị giao diện người dùng.
- Dữ liệu, chẳng hạn như tệp JSON, cần thiết để hiển thị trải nghiệm cơ bản.
- Phông chữ trên web.
- Trên một ứng dụng nhiều trang, các tài liệu HTML khác mà bạn muốn phân phát nhanh hoặc khi không có mạng.
Sẵn sàng dùng khi không có mạng
Mặc dù khả năng hoạt động khi không có mạng là một trong những yêu cầu đối với Ứng dụng web tiến bộ, nhưng điều quan trọng là bạn phải hiểu rằng không phải mọi PWA đều cần có trải nghiệm đầy đủ khi không có mạng, ví dụ: các giải pháp chơi trò chơi trên đám mây hoặc ứng dụng tài sản tiền mã hoá. Do đó, bạn có thể cung cấp một giao diện người dùng cơ bản để hướng dẫn người dùng trong những trường hợp đó.
PWA của bạn không được hiển thị thông báo lỗi của trình duyệt cho biết công cụ kết xuất web không thể tải trang. Thay vào đó, hãy sử dụng worker dịch vụ để hiển thị thông báo của riêng bạn, tránh lỗi trình duyệt chung và gây nhầm lẫn.
Bạn có thể sử dụng nhiều chiến lược lưu vào bộ nhớ đệm tuỳ thuộc vào nhu cầu của PWA. Đó là lý do bạn cần thiết kế cách sử dụng bộ nhớ đệm để mang lại trải nghiệm nhanh chóng và đáng tin cậy. Ví dụ: nếu tất cả tài sản ứng dụng của bạn sẽ tải xuống nhanh, không chiếm nhiều dung lượng và không cần cập nhật trong mỗi yêu cầu, thì việc lưu tất cả tài sản vào bộ nhớ đệm sẽ là một chiến lược hợp lệ. Mặt khác, nếu có các tài nguyên cần phải là phiên bản mới nhất, bạn nên cân nhắc việc không lưu các tài sản đó vào bộ nhớ đệm.
Sử dụng API
Sử dụng API Bộ nhớ đệm để xác định một tập hợp bộ nhớ đệm trong nguồn gốc của bạn, mỗi bộ nhớ đệm được xác định bằng một tên chuỗi mà bạn có thể xác định. Truy cập vào API thông qua đối tượng caches
và phương thức open
cho phép tạo hoặc mở bộ nhớ đệm đã tạo. Phương thức mở trả về một lời hứa cho đối tượng bộ nhớ đệm.
caches.open("pwa-assets")
.then(cache => {
// you can download and store, delete or update resources with cache arguments
});
Tải và lưu trữ thành phần
Để yêu cầu trình duyệt tải xuống và lưu trữ các thành phần, hãy sử dụng phương thức add
hoặc addAll
. Phương thức add
tạo một yêu cầu và lưu trữ một phản hồi HTTP, còn addAll
là một nhóm phản hồi HTTP dưới dạng một giao dịch dựa trên một mảng các yêu cầu hoặc URL.
caches.open("pwa-assets")
.then(cache => {
cache.add("styles.css"); // it stores only one resource
cache.addAll(["styles.css", "app.js"]); // it stores two resources
});
Giao diện bộ nhớ đệm lưu trữ toàn bộ phản hồi, bao gồm cả tất cả tiêu đề và nội dung. Do đó, bạn có thể truy xuất thông tin đó sau bằng cách sử dụng một yêu cầu HTTP hoặc URL làm khoá. Bạn sẽ tìm hiểu cách thực hiện việc đó trong chương Phân phát.
Thời điểm lưu vào bộ nhớ đệm
Trong PWA, bạn chịu trách nhiệm quyết định thời điểm lưu tệp vào bộ nhớ đệm. Mặc dù một phương pháp là lưu trữ nhiều thành phần nhất có thể khi cài đặt trình chạy dịch vụ, nhưng đây thường không phải là ý tưởng hay nhất. Việc lưu các tài nguyên không cần thiết vào bộ nhớ đệm sẽ làm lãng phí băng thông và không gian lưu trữ, đồng thời có thể khiến ứng dụng của bạn phân phát các tài nguyên đã lỗi thời ngoài dự kiến.
Bạn không cần lưu tất cả thành phần vào bộ nhớ đệm cùng một lúc, mà có thể lưu nhiều lần trong vòng đời của PWA, chẳng hạn như:
- Khi cài đặt trình chạy dịch vụ.
- Sau lần tải trang đầu tiên.
- Khi người dùng điều hướng đến một phần hoặc tuyến đường.
- Khi mạng ở trạng thái rảnh.
Bạn có thể yêu cầu lưu các tệp mới vào bộ nhớ đệm trong luồng chính hoặc trong ngữ cảnh của worker dịch vụ.
Lưu các thành phần vào bộ nhớ đệm trong worker dịch vụ
Một trong những trường hợp phổ biến nhất là lưu một nhóm tài sản tối thiểu vào bộ nhớ đệm khi cài đặt worker dịch vụ. Để làm việc đó, bạn có thể sử dụng giao diện bộ nhớ đệm trong sự kiện install
trong worker dịch vụ.
Vì luồng worker dịch vụ có thể bị dừng bất cứ lúc nào, nên bạn có thể yêu cầu trình duyệt đợi lời hứa addAll
hoàn tất để tăng cơ hội lưu trữ tất cả tài sản và duy trì tính nhất quán của ứng dụng. Ví dụ sau đây minh hoạ cách thực hiện việc này, sử dụng phương thức waitUntil
của đối số sự kiện nhận được trong trình nghe sự kiện của worker dịch vụ.
const urlsToCache = ["/", "app.js", "styles.css", "logo.svg"];
self.addEventListener("install", event => {
event.waitUntil(
caches.open("pwa-assets")
.then(cache => {
return cache.addAll(urlsToCache);
});
);
});
Phương thức waitUntil()
nhận một lời hứa và yêu cầu trình duyệt đợi tác vụ trong lời hứa được phân giải (đã thực hiện hoặc không thành công) trước khi chấm dứt quy trình worker dịch vụ. Bạn có thể cần phải tạo chuỗi các lời hứa và trả về lệnh gọi add()
hoặc addAll()
để một kết quả duy nhất được chuyển đến phương thức waitUntil()
.
Bạn cũng có thể xử lý các lời hứa bằng cú pháp async/await. Trong trường hợp đó, bạn cần tạo một hàm không đồng bộ có thể gọi await
và trả về một lời hứa cho waitUntil()
sau khi được gọi, như trong ví dụ sau:
const urlsToCache = ["/", "app.js", "styles.css", "logo.svg"];
self.addEventListener("install", (event) => {
let cacheUrls = async () => {
const cache = await caches.open("pwa-assets");
return cache.addAll(urlsToCache);
};
event.waitUntil(cacheUrls());
});
Yêu cầu trên nhiều miền và phản hồi không rõ ràng
PWA có thể tải xuống và lưu các thành phần vào bộ nhớ đệm từ nguồn gốc và trên nhiều miền, chẳng hạn như nội dung từ CDN của bên thứ ba. Với ứng dụng trên nhiều miền, hoạt động tương tác với bộ nhớ đệm rất giống với các yêu cầu trên cùng một nguồn gốc. Yêu cầu được thực thi và một bản sao của phản hồi được lưu trữ trong bộ nhớ đệm. Giống như các thành phần khác được lưu vào bộ nhớ đệm, thành phần này chỉ có thể được sử dụng trong nguồn gốc của ứng dụng.
Tài sản này sẽ được lưu trữ dưới dạng phản hồi mờ, nghĩa là mã của bạn sẽ không thể xem hoặc sửa đổi nội dung hoặc tiêu đề của phản hồi đó. Ngoài ra, các phản hồi mờ không hiển thị kích thước thực tế trong API bộ nhớ, ảnh hưởng đến hạn mức. Một số trình duyệt hiển thị kích thước lớn, chẳng hạn như 7 Mb, bất kể tệp chỉ có 1 KB.
Cập nhật và xoá thành phần
Bạn có thể cập nhật thành phần bằng cache.put(request, response)
và xoá thành phần bằng delete(request)
.
Hãy xem tài liệu về đối tượng bộ nhớ đệm để biết thêm thông tin chi tiết.
Gỡ lỗi bộ nhớ đệm
Nhiều trình duyệt cung cấp cách gỡ lỗi nội dung của bộ nhớ đệm trong thẻ Ứng dụng DevTools. Tại đó, bạn có thể xem nội dung của mọi bộ nhớ đệm trong nguồn hiện tại. Chúng ta sẽ đề cập thêm về các công cụ này trong chương Công cụ và gỡ lỗi.