프로그레시브 웹 앱: Workbox 사용

1. 환영합니다

이 실습에서는 기존 서비스 워커가 있는 웹사이트를 가져와 Workbox를 사용하도록 변환합니다. 이 Codelab은 프로그레시브 웹 앱 워크숍의 동반 Codelab 시리즈 중 두 번째입니다. 이전 Codelab은 오프라인으로 전환이었습니다. 이 시리즈에는 6개의 Codelab이 더 있습니다.

학습할 내용

  • Workbox를 사용하도록 기존 서비스 워커 변환
  • PWA에 오프라인 대체 추가

유의해야 할 사항

  • 기본 HTML 및 JavaScript

필요한 항목

2. 설정하기

이 Codelab을 완료하는 데 필요한 시작 코드를 클론하거나 다운로드하여 시작하세요.

저장소를 클론하는 경우 pwa03--workbox 브랜치에 있는지 확인합니다. ZIP 파일에는 해당 브랜치의 코드도 포함되어 있습니다.

이 코드베이스에는 Node.js 14 이상이 필요합니다. 코드를 사용할 수 있게 되면 코드 폴더의 명령줄에서 npm ci를 실행하여 필요한 모든 종속 항목을 설치합니다. 그런 다음 npm start를 실행하여 Codelab의 개발 서버를 시작합니다.

소스 코드의 README.md 파일은 배포된 모든 파일에 대한 설명을 제공합니다. 또한 이 Codelab 전반에서 작업할 주요 기존 파일은 다음과 같습니다.

키 파일

  • service-worker.js - 애플리케이션의 서비스 워커 파일
  • offline.html - 페이지를 사용할 수 없을 때 사용할 오프라인 HTML

3. Workbox로 이전

기존 서비스 워커를 살펴보면 사전 캐싱은 다음과 같은 두 단계로 나눌 수 있습니다.

  • 서비스 워커 설치 중에 관련 파일 캐시
  • 캐시 전용 전략으로 해당 파일을 다시 제공합니다.

index.html 파일과 / 경로 모두 사전 캐시하는 것이 여전히 합리적입니다. 이 웹 앱의 HTML은 크게 변경되지 않지만 CSS 및 JavaScript와 같은 다른 파일은 변경될 수 있으며 변경될 때마다 전체 서비스 워커 수명 주기를 거치고 싶지는 않습니다. 또한 현재 서비스 워커는 CSS 및 JavaScript의 일부만 고려하므로 모든 항목을 포함하고 싶습니다. 이러한 항목을 Stale While Revalidate 전략으로 캐싱하는 것이 더 합리적입니다. 필요에 따라 백그라운드에서 업데이트할 수 있는 빠른 응답이 제공되기 때문입니다.

재방문한 사전 캐싱

Workbox로 이전하면 기존 코드를 유지할 필요가 없으므로 service-worker.js의 모든 항목을 삭제합니다. 이전 실습에서는 이 서비스 워커가 컴파일되도록 설정했으므로 여기에서 ESModule 가져오기를 사용하여 NPM 모듈에서 Workbox를 가져올 수 있습니다. 먼저 사전 캐싱을 다시 살펴보겠습니다. service-worker.js에서 다음 코드를 추가합니다.

import { warmStrategyCache } from 'workbox-recipes';
import { CacheFirst } from 'workbox-strategies';
import { registerRoute } from 'workbox-routing';
import { CacheableResponsePlugin } from 'workbox-cacheable-response';
import { ExpirationPlugin } from 'workbox-expiration';

// Set up page cache
const pageCache = new CacheFirst({
  cacheName: 'page-cache',
  plugins: [
    new CacheableResponsePlugin({
      statuses: [0, 200],
    }),
    new ExpirationPlugin({
      maxAgeSeconds: 30 * 24 * 60 * 60,
    }),
  ],
});

warmStrategyCache({
  urls: ['/index.html', '/'],
  strategy: pageCache,
});

registerRoute(({ request }) => request.mode === 'navigate', pageCache);

설명

/index.html/의 사전 캐싱을 설정하려면 가져올 모듈이 5개 있습니다. 많은 것처럼 보일 수 있지만 이 코드는 이전에 작성된 코드보다 훨씬 강력합니다.

필요에 따라 다른 페이지를 캐시에 추가할 수 있도록 Cache Only 전략 대신 선택된 새로운 Cache First 캐싱 전략을 설정하는 것으로 시작합니다. 이름이 지정됩니다(page-cache). Workbox 전략은 캐시에서 콘텐츠를 저장하고 검색하는 수명 주기에 영향을 줄 수 있는 여러 플러그인을 사용할 수 있습니다. 여기에서는 캐시 가능한 응답 플러그인과 만료 플러그인이라는 두 개의 플러그인을 사용하여 양호한 서버 응답만 캐시되고 캐시의 각 항목이 30일 후에 삭제되도록 합니다.

그런 다음 따뜻한 전략 캐시 Workbox 레시피를 사용하여 /index.html/로 전략의 캐시가 워밍됩니다. 이렇게 하면 서비스 워커의 설치 이벤트 중에 해당 항목이 이 캐시에 추가됩니다.

마지막으로 새 경로가 등록됩니다. 페이지 탐색인 요청은 캐시에서 가져오거나 네트워크에서 가져온 후 응답을 캐시하는 이 Cache First 전략에 의해 관리됩니다.

애셋 캐싱

경로 미리 캐싱이 완료되었으므로 사이트 애셋(CSS 및 JavaScript)의 캐싱을 다시 구현할 차례입니다. 이렇게 하려면 먼저 workbox-strategies 가져오기에 StaleWhileRevalidate를 추가한 다음 서비스 워커 하단에 다음 코드를 추가하세요.

// Set up asset cache
registerRoute(
  ({ request }) => ['style', 'script', 'worker'].includes(request.destination),
  new StaleWhileRevalidate({
    cacheName: 'asset-cache',
    plugins: [
      new CacheableResponsePlugin({
        statuses: [0, 200],
      }),
    ],
  }),
);

설명

이 경로는 요청 유형이 스타일, 스크립트 또는 작업자인지 확인하는 것으로 시작합니다. 이는 CSS, JavaScript 또는 웹 작업자에 해당합니다. 그렇다면 Stale While Revalidate 전략을 사용하여 먼저 캐시에서 제공하려고 시도하고, 사용할 수 없는 경우 네트워크로 대체하며, 가능한 경우 네트워크에서 캐시의 버전을 업데이트하려고 시도합니다. 페이지 전략과 마찬가지로 이 전략은 양호한 응답만 캐시합니다.

4. 오프라인 대체 추가

원래 서비스 워커가 Workbox로 이전되었으므로 오프라인일 때 PWA가 비정상 종료되지 않도록 하려면 오프라인 대체 항목을 추가해야 합니다.

오프라인 대체는 오프라인일 때 사용할 수 없는 모든 항목(페이지, 글꼴, CSS, JavaScript, 이미지 등)에 설정할 수 있습니다. 최소한 모든 PWA에 페이지 대체가 설정되어 있어야 합니다. 그래야 사용자가 캐시에 없는 페이지로 이동할 때 앱 컨텍스트 내에 머물게 됩니다.

Workbox 레시피는 바로 이 작업을 실행하는 데 사용할 수 있는 오프라인 대체 레시피를 제공합니다. 이를 사용하려면 먼저 workbox-recipes 가져오기에 offlineFallback를 추가한 다음 서비스 워커 하단에 다음 코드를 추가합니다.

// Set up offline fallback
offlineFallback({
  pageFallback: '/offline.html',
});

설명

오프라인 대체 레시피는 제공된 대체로 워밍되는 캐시 전용 전략을 설정합니다. 그런 다음 Workbox 기본 catch 핸들러를 설정하여 실패한 라우팅 요청을 포착하고 (캐시에 아무것도 없고 네트워크에서 연결할 수 없는 경우) 요청이 계속 실패하는 한 캐시에서 관련 파일의 콘텐츠를 가져와 콘텐츠로 반환합니다.

5. 축하합니다.

Workbox를 사용하여 경로의 캐싱 전략을 설정하고 PWA의 오프라인 대체 항목을 제공하는 방법을 알아봤습니다.

이 시리즈의 다음 Codelab은 IndexedDB입니다.