# 折腾小记 – Service Worker

## 1 Service Worker

The service worker is designed first to redress this balance by providing a Web Worker context, which can be started by a runtime when navigations are about to occur. This event-driven worker is registered against an origin and a path (or pattern), meaning it can be consulted when navigations occur to that location. Events that correspond to network requests are dispatched to the worker and the responses generated by the worker may override default network stack behavior. This puts the service worker, conceptually, between the network and a document renderer, allowing the service worker to provide content for documents, even while offline.

https://www.w3.org/TR/service-workers/#motivations

Service Worker 提供了一种在请求前进行处理的 Web Worker。开发者可以通过此技术来拦截并修改每一个请求，并通过访问缓存等方式实现在网络较差甚至离线情况下对网页的访问。

### 1.2 一些技术细节

Service Worker 是有一个注册流程的。

1. 如果之前没有 Service Worker，那么经过 ServiceWorkerContainer.register() 方法注册，如果代码运行成功，那么 Service Worker 进入 Installed 状态。
2. 在之后的访问，每次都会使用这一次注册的 Service Worker，也就是 Activate 状态。如果 Service Worker 文件发生变化，那么新的文件会进入 Waiting 状态。在关于注册域的所有网页都已经被关闭后，原有的 Service Worker 文件被回收，新的 Service Worker 将在下一次访问时开始工作。

Service Worker 有注册域（scope）的概念。

Service Worker 只在访问注册域下的页面时工作。

### 1.3 事件和方法

You can listen for the install event; a standard action is to prepare your service worker for usage when this fires, for example by creating a cache using the built in storage API, and placing assets inside it that you’ll want for running your app offline.

There is also an activate event. The point where this event fires is generally a good time to clean up old caches and other things associated with the previous version of your service worker.

https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API

install 事件；通常用于预加载需要的文件。

activate 事件；通常用于清除上一版本的 Service Worker 留下的缓存和其他东西。

Your service worker can respond to requests using the FetchEvent event. You can modify the response to these requests in any way you want, using the FetchEvent.respondWith() method.

https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API

fetch 事件；监听每一个请求，可以通过 FetchEvent.respondWith() 方法来指定回应方式。

A Response or a Promise that resolves to a Response. Otherwise, a network error is returned to Fetch.

https://developer.mozilla.org/en-US/docs/Web/API/FetchEvent/respondWith

## 2 本站的实现

activate 事件中，将非当前版本的缓存池删除，以去除老版本留下的缓存。

fetch 事件中，当前仅当 wp-contentwp-include 目录下的文件会被放入 staticfiles，其他文件会放入 cachefiles

• staticfiles 的文件会优先读取缓存，如果没有命中缓存，则请求并放入缓存。
• cachefiles 的文件会优先请求最新资源并放入缓存，如果无法连接，则返回缓存内的文件。