Lưu tài nguyên vào bộ nhớ đệm trong thời gian chạy

Một số thành phần trong ứng dụng web của bạn có thể không được sử dụng thường xuyên, có kích thước rất lớn hoặc thay đổi tuỳ theo thiết bị của người dùng (chẳng hạn như hình ảnh thích ứng) hoặc ngôn ngữ. Đây là những trường hợp việc lưu vào bộ nhớ đệm có thể không giống mẫu và bạn nên dựa vào chức năng lưu vào bộ nhớ đệm trong thời gian chạy.

Trong Workbox, bạn có thể xử lý việc lưu vào bộ nhớ đệm trong thời gian chạy cho các tài sản bằng cách sử dụng mô-đun workbox-routing để khớp các tuyến và xử lý các chiến lược lưu vào bộ nhớ đệm cho các tài sản đó bằng mô-đun workbox-strategies.

Chiến lược lưu vào bộ nhớ đệm

Bạn có thể xử lý hầu hết các tuyến của tài sản bằng một trong các chiến lược lưu vào bộ nhớ đệm tích hợp sẵn. Những nguyên tắc này đã được đề cập chi tiết ở phần trước của tài liệu này, nhưng sau đây là một vài điểm đáng tóm tắt:

  • Lỗi thời trong khi xác thực lại sử dụng một phản hồi được lưu vào bộ nhớ đệm cho một yêu cầu (nếu có) và cập nhật bộ nhớ đệm ở chế độ nền bằng một phản hồi của mạng. Do đó, nếu nội dung không được lưu vào bộ nhớ đệm thì nội dung sẽ đợi phản hồi của mạng và sử dụng nội dung đó. Đây là một chiến lược khá an toàn vì nó thường xuyên cập nhật các mục trong bộ nhớ đệm dựa vào phương thức này. Nhược điểm là luôn yêu cầu thành phần từ mạng ở chế độ nền.
  • Trước tiên, Network First sẽ cố gắng nhận phản hồi từ mạng. Nếu nhận được một phản hồi, nó sẽ chuyển phản hồi đó đến trình duyệt và lưu vào bộ nhớ đệm. Nếu yêu cầu mạng không thành công, thì phản hồi được lưu vào bộ nhớ đệm gần đây nhất sẽ được sử dụng, cho phép bạn truy cập ngoại tuyến vào nội dung.
  • Trước tiên, Cache First sẽ kiểm tra bộ nhớ đệm để tìm phản hồi rồi sử dụng phản hồi đó nếu có. Nếu yêu cầu không có trong bộ nhớ đệm, mạng sẽ được sử dụng và mọi phản hồi hợp lệ sẽ được thêm vào bộ nhớ đệm trước khi được chuyển tới trình duyệt.
  • Chỉ mạng buộc phản hồi phải đến từ mạng.
  • Chỉ bộ nhớ đệm buộc phản hồi phải đến từ bộ nhớ đệm.

Bạn có thể áp dụng các chiến lược này cho một số yêu cầu bằng phương thức do workbox-routing cung cấp.

Áp dụng chiến lược lưu vào bộ nhớ đệm với so khớp tuyến

workbox-routing hiển thị một phương thức registerRoute để so khớp các tuyến và xử lý các tuyến đó bằng chiến lược lưu vào bộ nhớ đệm. registerRoute chấp nhận đối tượng Route và đối tượng này cũng chấp nhận 2 đối số:

  1. Chuỗi, biểu thức chính quy hoặc lệnh gọi lại so khớp để chỉ định tiêu chí so khớp tuyến.
  2. Trình xử lý cho tuyến—thường là chiến lược do workbox-strategies cung cấp.

Những lệnh gọi lại so khớp được ưu tiên hơn so với các tuyến đường vì chúng cung cấp một đối tượng ngữ cảnh bao gồm đối tượng Request, chuỗi URL yêu cầu, sự kiện tìm nạp và giá trị boolean cho biết yêu cầu đó có phải là yêu cầu cùng nguồn gốc hay không.

Sau đó, trình xử lý này sẽ xử lý tuyến được so khớp. Trong ví dụ sau, một tuyến mới được tạo để khớp với các yêu cầu hình ảnh cùng nguồn gốc sắp tới, áp dụng bộ nhớ đệm trước, quay lại chiến lược mạng.

// sw.js
import { registerRoute, Route } from 'workbox-routing';
import { CacheFirst } from 'workbox-strategies';

// A new route that matches same-origin image requests and handles
// them with the cache-first, falling back to network strategy:
const imageRoute = new Route(({ request, sameOrigin }) => {
  return sameOrigin && request.destination === 'image'
}, new CacheFirst());

// Register the new route
registerRoute(imageRoute);

Sử dụng nhiều bộ nhớ đệm

Workbox cho phép bạn nhóm các phản hồi được lưu vào bộ nhớ đệm vào các thực thể Cache riêng biệt bằng cách sử dụng tuỳ chọn cacheName có sẵn trong các chiến lược đi kèm.

Trong ví dụ sau, hình ảnh sử dụng chiến lược cũ trong khi xác thực lại, trong khi các thành phần CSS và JavaScript sử dụng chiến lược dựa trên bộ nhớ đệm trước tiên để quay lại sử dụng chiến lược mạng. Tuyến cho mỗi thành phần sẽ đặt phản hồi vào các bộ nhớ đệm riêng biệt, bằng cách thêm thuộc tính cacheName.

// sw.js
import { registerRoute, Route } from 'workbox-routing';
import { CacheFirst, StaleWhileRevalidate } from 'workbox-strategies';

// Handle images:
const imageRoute = new Route(({ request }) => {
  return request.destination === 'image'
}, new StaleWhileRevalidate({
  cacheName: 'images'
}));

// Handle scripts:
const scriptsRoute = new Route(({ request }) => {
  return request.destination === 'script';
}, new CacheFirst({
  cacheName: 'scripts'
}));

// Handle styles:
const stylesRoute = new Route(({ request }) => {
  return request.destination === 'style';
}, new CacheFirst({
  cacheName: 'styles'
}));

// Register routes
registerRoute(imageRoute);
registerRoute(scriptsRoute);
registerRoute(stylesRoute);
Ảnh chụp màn hình danh sách các thực thể Cache trong thẻ ứng dụng của Công cụ cho nhà phát triển của Chrome. Có 3 bộ nhớ đệm riêng biệt được hiển thị: một bộ nhớ đệm có tên là "tập lệnh", một bộ nhớ đệm khác có tên là "kiểu" và bộ nhớ đệm cuối cùng có tên là "hình ảnh".
Trình xem bộ nhớ đệm trong bảng điều khiển Ứng dụng của Công cụ cho nhà phát triển của Chrome. Phản hồi cho các loại thành phần khác nhau được lưu trữ trong các bộ nhớ đệm riêng.

Thiết lập ngày hết hạn cho các mục nhập bộ nhớ đệm

Lưu ý về hạn mức bộ nhớ khi quản lý(các) bộ nhớ đệm của trình chạy dịch vụ. ExpirationPlugin đơn giản hoá việc bảo trì bộ nhớ đệm và được cung cấp bởi workbox-expiration. Để sử dụng phương thức này, hãy chỉ định phương thức này trong cấu hình cho chiến lược lưu vào bộ nhớ đệm:

// sw.js
import { registerRoute, Route } from 'workbox-routing';
import { CacheFirst } from 'workbox-strategies';
import { ExpirationPlugin } from 'workbox-expiration';

// Evict image cache entries older thirty days:
const imageRoute = new Route(({ request }) => {
  return request.destination === 'image';
}, new CacheFirst({
  cacheName: 'images',
  plugins: [
    new ExpirationPlugin({
      maxAgeSeconds: 60 * 60 * 24 * 30,
    })
  ]
}));

// Evict the least-used script cache entries when
// the cache has more than 50 entries:
const scriptsRoute = new Route(({ request }) => {
  return request.destination === 'script';
}, new CacheFirst({
  cacheName: 'scripts',
  plugins: [
    new ExpirationPlugin({
      maxEntries: 50,
    })
  ]
}));

// Register routes
registerRoute(imageRoute);
registerRoute(scriptsRoute);
được định cấu hình

Việc tuân thủ hạn mức bộ nhớ có thể rất phức tạp. Bạn nên xem xét những người dùng có thể đang gặp áp lực về việc lưu trữ hoặc muốn sử dụng bộ nhớ hiệu quả nhất. Các cặp ExpirationPlugin của Workbox có thể giúp bạn đạt được mục tiêu đó.

Những điểm cần lưu ý trên nhiều nguồn gốc

Mức độ tương tác giữa trình chạy dịch vụ và tài sản trên nhiều nguồn gốc của bạn khác biệt đáng kể so với hoạt động tương tác với tài sản cùng nguồn gốc. Chia sẻ tài nguyên trên nhiều nguồn gốc (CORS) rất phức tạp và sự phức tạp đó cũng ảnh hưởng đến cách bạn xử lý các tài nguyên trên nhiều nguồn gốc trong một trình chạy dịch vụ.

Phản hồi mờ

Khi thực hiện một yêu cầu trên nhiều nguồn gốc ở chế độ no-cors, phản hồi có thể được lưu trữ trong bộ nhớ đệm của trình chạy dịch vụ và thậm chí còn được trình duyệt sử dụng trực tiếp. Tuy nhiên, bản thân nội dung phản hồi không thể đọc qua JavaScript. Đây được gọi là phản hồi mờ.

Phản hồi mờ là một biện pháp bảo mật nhằm ngăn chặn việc kiểm tra tài sản nhiều nguồn gốc. Bạn vẫn có thể đưa ra yêu cầu đối với tài sản trên nhiều nguồn gốc và thậm chí là lưu các tài sản đó vào bộ nhớ đệm, nhưng bạn chỉ không thể đọc nội dung phản hồi hoặc thậm chí không thể đọc mã trạng thái của nội dung phản hồi!

Nhớ chọn sử dụng chế độ CORS

Ngay cả khi bạn tải các thành phần trên nhiều nguồn gốc mà đặt tiêu đề CORS tuỳ ý cho phép bạn đọc phản hồi, thì phần nội dung của phản hồi trên nhiều nguồn gốc có thể vẫn không rõ ràng. Ví dụ: HTML sau đây sẽ kích hoạt các yêu cầu no-cors dẫn đến phản hồi mờ bất kể tiêu đề CORS được đặt là gì:

<link rel="stylesheet" href="https://example.com/path/to/style.css">
<img src="https://example.com/path/to/image.png">

Để kích hoạt một yêu cầu cors một cách rõ ràng mà sẽ tạo ra phản hồi không mờ, bạn cần chọn sử dụng chế độ CORS một cách rõ ràng bằng cách thêm thuộc tính crossorigin vào HTML của mình:

<link crossorigin="anonymous" rel="stylesheet" href="https://example.com/path/to/style.css">
<img crossorigin="anonymous" src="https://example.com/path/to/image.png">

Điều quan trọng cần nhớ là khi các tuyến trong trình chạy dịch vụ của bạn lưu tài nguyên phụ vào bộ nhớ đệm trong thời gian chạy.

Hộp làm việc có thể không lưu các phản hồi mờ vào bộ nhớ đệm

Theo mặc định, Workbox sử dụng biện pháp thận trọng để lưu các phản hồi mờ vào bộ nhớ đệm. Vì không thể kiểm tra mã phản hồi cho các phản hồi mờ, do đó việc lưu một phản hồi lỗi vào bộ nhớ đệm có thể dẫn đến trải nghiệm liên tục bị lỗi nếu sử dụng chiến lược ưu tiên bộ nhớ đệm hoặc chiến lược chỉ dành cho bộ nhớ đệm.

Nếu cần lưu một phản hồi mờ vào bộ nhớ đệm trong Workbox, bạn nên sử dụng chiến lược ưu tiên mạng hoặc cũ trong khi xác thực để xử lý phản hồi đó. Có, điều này có nghĩa là mạng lưới luôn yêu cầu thành phần này. Tuy nhiên, thành phần này đảm bảo rằng các phản hồi không thành công sẽ không tiếp tục và cuối cùng sẽ được thay thế bằng các phản hồi hữu dụng.

Nếu bạn sử dụng một chiến lược lưu vào bộ nhớ đệm khác và một phản hồi mờ được trả về, thì Workbox sẽ cảnh báo bạn rằng phản hồi đó không được lưu vào bộ nhớ đệm khi ở chế độ phát triển.

Buộc lưu các phản hồi mờ vào bộ nhớ đệm

Nếu hoàn toàn chắc chắn rằng mình muốn lưu phản hồi mờ vào bộ nhớ đệm bằng chiến lược ưu tiên bộ nhớ đệm hoặc chiến lược chỉ lưu vào bộ nhớ đệm, bạn có thể buộc Workbox thực hiện việc này bằng mô-đun workbox-cacheable-response:

import {Route, registerRoute} from 'workbox-routing';
import {NetworkFirst, StaleWhileRevalidate} from 'workbox-strategies';
import {CacheableResponsePlugin} from 'workbox-cacheable-response';

const cdnRoute = new Route(({url}) => {
  return url === 'https://cdn.google.com/example-script.min.js';
}, new CacheFirst({
  plugins: [
    new CacheableResponsePlugin({
      statuses: [0, 200]
    })
  ]
}))

registerRoute(cdnRoute);

Phản hồi mờ và API navigator.storage

Để tránh rò rỉ thông tin trên nhiều miền, cần có thêm khoảng đệm đáng kể vào kích thước của một phản hồi mờ dùng để tính toán giới hạn hạn mức bộ nhớ. Điều này ảnh hưởng đến cách API navigator.storage báo cáo hạn mức bộ nhớ.

Khoảng đệm này sẽ khác nhau tuỳ theo trình duyệt, nhưng đối với Chrome, kích thước tối thiểu mà mọi phản hồi mờ được lưu vào bộ nhớ đệm đều đóng góp vào tổng bộ nhớ được sử dụng là khoảng 7 megabyte. Bạn nên lưu ý điều này khi xác định số lượng phản hồi mờ muốn lưu vào bộ nhớ đệm, vì bạn có thể dễ dàng vượt quá hạn mức bộ nhớ sớm hơn nhiều so với dự kiến.