대체 응답 관리

특정 상황에서 사용자가 오프라인 상태인 경우에 대비해 대체 응답을 캐시하고자 할 수 있습니다. 네트워크 우선 또는 비활성 재검증과 같은 전략에서 제공하는 캐싱 동작 대신 대체를 구현할 수 있습니다.

대체는 요청 실패 시 브라우저가 기본적으로 제공하는 것보다 나은 자리표시자인 모든 경우에 적용되는 일반적 응답입니다. 다음은 몇 가지 예시입니다.

  • '누락된 이미지' 자리표시자의 대안입니다.
  • 표준 '네트워크에 연결할 수 없음' 페이지의 대체 HTML입니다.

오프라인 페이지만

맞춤 오프라인 HTML 페이지만 제공하면 되는 경우, 다음과 같은 기본 레시피를 따르면 됩니다.

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

setDefaultHandler(new NetworkOnly());

offlineFallback();

위 코드는 setDefaultHandler를 사용하여 모든 경로의 네트워크 전용 전략을 기본값으로 사용합니다. 그런 다음 오류가 발생하는 경우 offlineFallback 레시피를 실행하여 오프라인 대체를 제공합니다. 이 레시피에서는 오프라인 대체 HTML 파일의 이름이 offline.html이고 웹 서버의 루트에서 제공된다고 가정합니다.

포괄적인 대체

네트워크 장애 또는 캐시 부적중이 발생할 때마다 workbox-strategies에서 제공하는 캐싱 전략이 일관되게 거부됩니다. 이렇게 하면 단일 핸들러 함수에서 실패를 처리하기 위해 전역 'catch' 핸들러를 설정하는 패턴이 향상되므로 다양한 request.destination 값에 다양한 대체 값을 제공할 수 있습니다.

다음 예에서는 workbox-recipeswarmStrategyCache 레시피를 사용하고 런타임 캐시에서 미리 캐시된 항목을 제공하도록 포착 핸들러를 설정합니다. 하지만 애플리케이션에는 사전 캐싱 대체가 더 적합할 수 있습니다.

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();
  }
});

다음에서 Workbox의 빌드 도구와 함께 injectManifest를 사용하여 대체 응답이 사전 캐시되며, 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();
  }
});

두 번째 대체 설정의 사용 사례로는 페이지가 미리 캐시되었지만 페이지에서 요청한 이미지 (또는 기타 애셋)는 캐시되지 않은 경우입니다. 사용자가 오프라인일 때도 캐시에서 페이지를 읽을 수 있지만 네트워크 오류가 발생하는 경우 대체 자리표시자 또는 대체 기능을 제공할 수 있습니다.

런타임 캐시 예열

Workbox는 사전 캐싱 및 런타임 캐시를 위해 별도의 캐시를 유지합니다. 사전 캐싱에 의존하지 않고 특정 항목을 미리 캐시하려는 상황이 발생할 수 있습니다. 사전 캐시 매니페스트를 업데이트하려면 업데이트된 서비스 워커를 배포해야 하기 때문입니다.

애셋으로 런타임 캐시를 미리 준비하려면 workbox-recipeswarmStrategyCache 레시피를 사용하면 됩니다. 내부적으로 이 전략은 서비스 워커의 install 이벤트에서 Cache.addAll를 호출합니다.

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});

결론

실패한 요청에 대한 대체 응답을 관리하려면 약간의 작업이 필요하지만 약간의 사전 계획을 통해 사용자가 오프라인 상태일 때 일정 수준의 콘텐츠와 기능을 제공하도록 웹 앱을 설정할 수 있습니다.