Workbox 간단 정리

vhv3y8·2024년 2월 24일
0

목록 보기
7/8

Workbox는 Service Worker를 쉽게 쓸 수 있게 약간의 추상화를 더해주는 라이브러리다.

구글 크롬 팀에서 만들었으며, 여러 개의 패키지로 분류되어 있어서 필요에 따라 일부만 갖다 쓰기에도 좋다고 한다.

Workbox의 큰 틀과 핵심적인 기능들에 대해 정리해보자.

  • 라우팅 (fetch)
    • workbox-routing
  • 캐싱 전략 (fetch)
    • workbox-strategies
  • 플러그인 패키지들
  • Precaching (install)
    • workbox-precaching
  • workbox-build

라우팅 (fetch)

fetch는 Service Worker에서 핵심적인 이벤트다.

네트워크 Request를 인터셉트해서 넘겨주기 때문에, Response를 캐시에서 가져올지 네트워크 요청을 보낼지 선택해서 처리할 수 있게 해준다.

// Service Worker에서
self.addEventListener("fetch", function (event) {
  const requestUrl = new URL(event.request.url)

  if (requestUrl.pathname.includes("/api/data")) {
    event.respondWith(customResponse())
  } else if (requestUrl.pathname.includes("/images")) {
    event.respondWith(customImageResponse())
  } else if (requestUrl.pathname.includes("/css")) {
    event.respondWith(customCSSResponse())
  } else {
    event.respondWith(fetch(event.request))
  }
})

다양한 Request를 받는 경우에는, 조건에 따라 처리하는 방식이 다를 것이고 그런 구분이 중요하다.

그럴 때 중요한 요소는, 어떤 Request를 받았냐그걸 어떻게 처리하느냐라고 할 수 있다.

workbox-routing

workbox-routing 패키지는 이럴 때 사용되는 "route"를 제공한다.

route는 어떤 Request를 받을 것이냐(matching)와 그걸 어떻게 처리할 것이냐(handling)로 구성된다.

import { registerRoute } from "workbox-routing"

registerRoute("https://example.com/api/data", () => {
  return new Response("Hello from the service worker!")
})

가장 대표적으로 쓰이는 메서드는 registerRoute()인데, matching 부분handler 부분을 순서대로 받는다.

matching에는 URL을 나타내는 string, 정규표현식, 함수 등이 올 수 있고,

handler 부분에는 함수나 객체가 올 수 있다고 한다.

자세한 내용은 문서 참고

어쨌든 라우팅은 fetch를 다루는 데에 있어서 핵심적이다.

캐싱 전략 (fetch)

그렇다면 handler 부분에 대해 조금 더 생각해보자.

fetch 이벤트는 Response 객체를 돌려줘야하므로, 대표적으로 캐시에서 가져오거나, 네트워크 요청을 보내서 처리할 수 있다.

workbox-strategies

이때 캐시네트워크 중 어디에서 먼저 가져오고, 실패할 경우에 어떻게 할 것인지에 따라 다양한 로직들이 생성될 수 있다.

그 로직들에 이름을 붙여주고 패턴화한 걸 캐싱 전략이라고 한다.

대표적인 캐싱 전략들과 그에 대응되는 constructor들은 다음과 같다 :

  • 캐시 먼저 (CacheFirst)
  • 캐시만 (CacheOnly)
  • 네트워크 먼저 (NetworkFirst)
  • 네트워크만 (NetworkOnly)
  • StaleWhileRevalidate (StaleWhileRevalidate)
    • 캐시에 있다면 우선 캐시에서 돌려준다. 그러고나서 네트워크 요청을 보내서 캐시를 업데이트한다.

NetworkFirst를 사용하는 예시를 보자 :

import { registerRoute } from "workbox-routing"
import { NetworkFirst } from "workbox-strategies"

registerRoute(
  ({ url }) => url.pathname.startsWith("/social-timeline/"),
  new NetworkFirst()
)

자세한 설명 및 예시는 문서 참고

플러그인 패키지들

캐싱 전략에서는 플러그인을 사용할 수 있는데, 플러그인을 제공하는 패키지들은 다음과 같다 :

  • workbox-background-sync
  • workbox-broadcast-update
  • workbox-cacheable-response
  • workbox-expiration
  • workbox-range-requests
import { registerRoute } from "workbox-routing"
import { CacheFirst } from "workbox-strategies"
import { ExpirationPlugin } from "workbox-expiration"

registerRoute(
  ({ request }) => request.destination === "image",
  new CacheFirst({
    cacheName: "image-cache",
    plugins: [
      new ExpirationPlugin({
        // Only cache requests for a week
        maxAgeSeconds: 7 * 24 * 60 * 60,
        // Only cache 10 requests.
        maxEntries: 10,
      }),
    ],
  })
)

이런 식으로 plugins에 넘겨주는 식으로 사용하는듯하다.

Precaching (install)

Service Worker의 또 다른 핵심 이벤트로는 install이 있다.

install은 Service Worker가 설치(다운로드, 업데이트) 되었을 때만 트리거 되며, 그래서 CacheStorage나 IndexedDB의 초기 세팅 등을 하는 용도로 사용된다.

// Service Worker에서
self.addEventListener("install", (event) => {
  event.waitUntil(
    caches.open("v1").then((cache) => {
      cache.addAll(["/", "/index.html", "/style.css", "/script.js"])
    })
  )
})

이런 초기 캐싱도 고정적이기 때문에 추상화할 수 있고, workbox-precaching 패키지가 그런 추상화를 제공한다.

workbox-precaching

import { precacheAndRoute } from "workbox-precaching"

precacheAndRoute(
  [
    { url: "/index.html", revision: "383676" },
    { url: "/styles/app.0c9a31.css", revision: null },
    { url: "/scripts/app.0d5770.js", revision: null },
  ],
  {
    // Ignore all URL parameters.
    ignoreURLParametersMatching: [/.*/],
  }
)

대표적으로 쓰이는 메서드는 precacheAndRoute()이며, 이 메서드에 넘겨주는 배열을 precache manifest라고 부르기도 한다고 한다.

이 route는 Cache-First 전략을 사용한다.

revision은 versioning information인데, url에 포함되어있으면 null을 주면 된다.

workbox-precaching은 이 정보를 통해 효율적으로 캐시를 업데이트한다고 한다.

이런 revision 정보는 직접 작성하면 안되고, 다음과 같은 패키지들을 통해 생성해야 한다 :

  • workbox-build
  • workbox-webpack-plugin
  • workbox-cli

workbox-build

workbox-build는 node 기반 빌드 프로세스에서 Service Worker 전체를 생성하거나 Precaching할 리스트를 생성하게 해주는 패키지다.

2가지 모드가 있다 :

  • generateSW
    • 파일 precaching
    • 런타임 캐싱
  • injectManifest
    • precaching할 파일 리스트를 생성
    • 기존에 존재하는 Service Worker 파일에 inject 해준다

자세한 내용은 문서 참고

참고

profile
개발 기록, 미래의 나에게 설명하기

0개의 댓글