Quản lý phản hồi dự phòng

Trong một số trường hợp, bạn nên lưu nội dung phản hồi dự phòng vào bộ nhớ đệm phòng khi người dùng không có kết nối mạng. Triển khai bản dự phòng là một giải pháp thay thế cho hành vi lưu vào bộ nhớ đệm mà các chiến lược như ưu tiên mạng hoặc lỗi thời trong khi xác thực lại cung cấp.

Dự phòng là phản hồi chung, phù hợp cho mọi trường hợp, là phần giữ chỗ hiệu quả hơn so với mặc định mà trình duyệt cung cấp khi một yêu cầu không thành công. Dưới đây là một số ví dụ:

  • Một giải pháp thay thế cho phần giữ chỗ "hình ảnh bị thiếu".
  • Phiên bản HTML thay thế cho trang tiêu chuẩn "không có kết nối mạng".

Chỉ trang ngoại tuyến

Nếu bạn chỉ cần cung cấp một trang HTML ngoại tuyến tuỳ chỉnh (nhưng không cần làm gì khác), thì sau đây là công thức cơ sở mà bạn có thể làm theo:

import {offlineFallback} from 'workbox-recipes';
import {setDefaultHandler} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';

setDefaultHandler(new NetworkOnly());

offlineFallback();

Mã ở trên dùng setDefaultHandler để sử dụng chiến lược chỉ mạng làm chiến lược mặc định cho tất cả các tuyến. Sau đó, hàm này chạy công thức offlineFallback để phân phát bản dự phòng ngoại tuyến trong trường hợp xảy ra lỗi. Công thức này giả định tệp HTML dự phòng ngoại tuyến của bạn sẽ có tên là offline.html và được phân phát từ thư mục gốc của máy chủ web.

Dự phòng toàn diện

Mỗi khi xảy ra lỗi mạng hoặc thiếu bộ nhớ đệm, các chiến lược lưu vào bộ nhớ đệm do workbox-strategies cung cấp sẽ luôn từ chối. Điều này thúc đẩy mẫu cài đặt trình xử lý "catch" chung để xử lý mọi lỗi trong một hàm xử lý duy nhất, cho phép bạn cung cấp nhiều phương án dự phòng cho nhiều giá trị request.destination.

Ví dụ sau đây sử dụng công thức warmStrategyCache của workbox-recipes và thiết lập trình xử lý catch để phân phát các mục được lưu trước vào bộ nhớ đệm trong thời gian chạy. Tuy nhiên, tính năng lưu trước bản dự phòng có thể phù hợp hơn với ứng dụng của bạn:

import {warmStrategyCache} from 'workbox-recipes';
import {setDefaultHandler, setCatchHandler} from 'workbox-routing';
import {CacheFirst, StaleWhileRevalidate} from 'workbox-strategies';

// Fallback assets to cache
const FALLBACK_HTML_URL = '/offline.html';
const FALLBACK_IMAGE_URL = '/images/image-not-found.jpg';
const FALLBACK_STRATEGY = new CacheFirst();

// Warm the runtime cache with a list of asset URLs
warmStrategyCache({
  urls: [FALLBACK_HTML_URL, FALLBACK_IMAGE_URL],
  strategy: FALLBACK_STRATEGY,
});

// Use a stale-while-revalidate strategy to handle requests by default.
setDefaultHandler(new StaleWhileRevalidate());

// This "catch" handler is triggered when any of the other routes fail to
// generate a response.
setCatchHandler(async ({request}) => {
  // The warmStrategyCache recipe is used to add the fallback assets ahead of
  // time to the runtime cache, and are served in the event of an error below.
  // Use `event`, `request`, and `url` to figure out how to respond, or
  // use request.destination to match requests for specific resource types.
  switch (request.destination) {
    case 'document':
      return FALLBACK_STRATEGY.handle({event, request: FALLBACK_HTML_URL});

    case 'image':
      return FALLBACK_STRATEGY.handle({event, request: FALLBACK_IMAGE_URL});

    default:
      // If we don't have a fallback, return an error response.
      return Response.error();
  }
});

Trong phần tiếp theo, các phản hồi dự phòng sẽ được lưu trước vào bộ nhớ đệm bằng injectManifest với các công cụ xây dựng của Workbox và được dùng làm dự phòng trong trường hợp xảy ra lỗi với phương thức matchPrecache.

import {matchPrecache, precacheAndRoute} from 'workbox-precaching';
import {setDefaultHandler, setCatchHandler} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';

// Optional: use the injectManifest mode of one of the Workbox
// build tools to precache a list of URLs, including fallbacks.
precacheAndRoute(self.__WB_MANIFEST);

// Use a stale-while-revalidate strategy to handle requests by default.
setDefaultHandler(new StaleWhileRevalidate());

// This "catch" handler is triggered when any of the other routes fail to
// generate a response.
setCatchHandler(async ({request}) => {
  // Fallback assets are precached when the service worker is installed, and are
  // served in the event of an error below. Use `event`, `request`, and `url` to
  // figure out how to respond, or use request.destination to match requests for
  // specific resource types.
  switch (request.destination) {
    case 'document':
      // FALLBACK_HTML_URL must be defined as a precached URL for this to work:
      return matchPrecache(FALLBACK_HTML_URL);

    case 'image':
      // FALLBACK_IMAGE_URL must be defined as a precached URL for this to work:
      return matchPrecache(FALLBACK_IMAGE_URL);

    default:
      // If we don't have a fallback, return an error response.
      return Response.error();
  }
});

Một trường hợp sử dụng mẫu cho thiết lập dự phòng thứ hai là khi một trang được lưu trước vào bộ nhớ đệm, nhưng hình ảnh (hoặc các thành phần khác) mà trang yêu cầu thì không. Người dùng vẫn có thể đọc trang từ bộ nhớ đệm khi không có kết nối mạng, nhưng họ có thể cung cấp phần giữ chỗ dự phòng hoặc chức năng thay thế nếu xảy ra lỗi mạng.

Làm nóng bộ nhớ đệm thời gian chạy

Workbox duy trì các bộ nhớ đệm riêng biệt để lưu trước và lưu vào bộ nhớ đệm trong thời gian chạy. Trong một số trường hợp, bạn có thể muốn lưu nội dung vào bộ nhớ đệm trước khi lưu vào bộ nhớ đệm mà không cần lưu vào bộ nhớ đệm trước, vì các bản cập nhật cho tệp kê khai lưu trước vào bộ nhớ đệm sẽ yêu cầu bạn triển khai một trình chạy dịch vụ được cập nhật.

Để trang bị trước các nội dung cho bộ nhớ đệm thời gian chạy, bạn có thể thực hiện việc này bằng cách sử dụng công thức warmStrategyCache trên workbox-recipes. Trong trường hợp này, chiến lược này sẽ gọi Cache.addAll trong sự kiện install của một trình chạy dịch vụ.

import {warmStrategyCache} from 'workbox-recipes';
import {CacheFirst} from 'workbox-strategies';

// This can be any strategy, CacheFirst used as an example.
const strategy = new CacheFirst();
const urls = [
  '/offline.html',
];

warmStrategyCache({urls, strategy});

Kết luận

Việc quản lý phản hồi dự phòng cho các yêu cầu không thành công tốn một chút công sức. Tuy nhiên, với một chút lập kế hoạch trước, bạn có thể thiết lập ứng dụng web của mình để cung cấp một số cấp độ nội dung và chức năng khi người dùng không kết nối mạng.