Fetch Event Handling in Service Workers
A service worker can observe eligible network requests through the `fetch` event and decide how the request should be fulfilled. This enables patterns such as network-first, cache-first, and offline fallbacks.
A service worker can register a `fetch` event listener. When the browser routes an eligible request through the service worker, the handler receives a `FetchEvent` containing the request and can inspect it before choosing a response strategy.
The main mechanism is `event.respondWith()`. Passing it a `Response` or a promise that resolves to a `Response` tells the browser to use that response instead of continuing with the browser's normal fetch handling. A handler can therefore call `fetch(event.request)`, read from `caches`, or combine both approaches.
A common pattern is cache-first: check the Cache API and return a cached response when available; otherwise fetch from the network and potentially cache the result. Network-first reverses the priority, using the network when possible and falling back to cached content when the request fails.
The handler should be selective about which requests it intercepts. For example, an application may handle only `GET` requests or only requests belonging to its own origin. Requests that are not relevant can simply be left alone by not calling `respondWith()`.
Because service workers run separately from the page, their fetch handling is asynchronous and must account for failures. Returning a rejected promise from `respondWith()` can result in a failed request, so offline strategies commonly provide an explicit fallback response.
Key points
- Register a `fetch` listener in the service worker.
- Use `event.request` to inspect the intercepted request.
- Call `event.respondWith()` to supply a custom response.
- Use the Cache API and `fetch()` to implement caching strategies.
- Skip requests that the service worker should not control.
Interview questions
How would you implement a simple cache-first strategy?
First, check the Cache API for a matching response. If one exists, return it immediately through `respondWith()`. If there is no match, perform `fetch(event.request)` and return the network response. A production implementation may also cache suitable network responses and define rules for which resources are safe to cache.
Why should a fetch handler avoid blindly intercepting every request?
A service worker can see requests that the application does not need to customize. Intercepting everything can add unnecessary work and can accidentally alter requests that require normal browser or network behavior. A handler can filter by method, origin, URL, or resource characteristics before calling `respondWith()`. Requests outside the intended scope can simply proceed normally.
What is the purpose of the `fetch` event in a service worker?
The `fetch` event lets a service worker react when an eligible request is handled through it. The handler can inspect `event.request` and choose how the request should be fulfilled. For example, it can return a cached response or perform a network fetch. This is a foundation for offline support and application caching strategies.
How does `event.respondWith()` work?
`respondWith()` tells the browser that the service worker will provide the response for the intercepted request. It accepts a `Response` or a promise that resolves to one. This allows asynchronous operations such as checking the Cache API or calling `fetch()`. It should be invoked while handling the fetch event.
What is the difference between a cache-first and network-first service-worker strategy?
Cache-first treats cached content as the preferred source and contacts the network when the cache does not contain a usable response. Network-first attempts to obtain fresh data from the network and falls back to cached content when the network is unavailable or fails. The choice depends on whether freshness or fast/offline availability is the stronger requirement. Either strategy should define cache update and failure behavior explicitly.