「译」5 分钟上手 Service Worker

作者:Carmen Bourlon
原文链接:Write Your First Service Worker in 5 Minutes

什么是 Service Worker?

Service Worker 是一个让你可以在用户机器上缓存文件和其他资源的小文件。那它跟服务器端缓存 (server-side caching) 有什么区别呢?这种缓存是放在用户的机器上的,因此跟服务器端的缓存相比,它不需要再通过网络传输。这对提升你的应用的速度和可靠性是非常有好处的。由于 app 是从缓存中运行的,就不用大费周章的花时间从网络传输数据了。

为什么说它对你的应用有好处

应用 Service Worker 不仅能提升应用的速度,还能为你的用户提供前所未有的可靠性。由于不再依赖实时的网络连接,应用在网络质量差的时候也能工作--说真的所有人的网络质量都不咋的。

生命周期

Service Worker 生命周期基本是这样:

  1. install
  2. Activate
  3. Fetch

我们来分别讲解一下这些事件:

Install

在 install 事件之前,你的应用里还没有 Service Worker。浏览器会从你的代码中检测注册事件并安装 Service Worker。你的 Service Worker 包含一个名为 oninstall 的函数,它将决定哪些文件会被缓存到用户的机器上。

Activate

在 Service Worker 安装就绪以后,会触发 activate 事件。此时是清理老旧无用的缓存文件的好时机。不过在这个例子中,我们并不会在 activate 事件里做任何操作。

Fetch

这是我们的 Service Worker 大显身手的时候。当应用发出 fetch 请求时,我们的 Service Worker 会用一个名字也是 fetch 的函数拦截它。你的 Service Worker 会从换从中寻找类似的请求或是将这个请求发送出去。

Service Worker 生命周期中 activate 和 fetch 并不是依次执行的。Fetch 只有在有 fetch 操作时才执行拦截,因此 activate 事件和 ftech 事件之间是有间隔的。在这间隔期间,Service Worker 处于待命状态。

Service Worker 示例

我们用 FayePI 来做例子。这是我写的一个帮助女性学习建设动态网站的 API,它的文档页面用了一点简单的 Service Worker。

为了安装 Service Worker,我们得先为应用添加一个注册函数。

1
2
3
4
5
// index.js

if(navigator.serviceWorker) {
navigator.serviceWorker.register('serviceworker.js');
}

上面这段代码通常放在 index.js 中以便在页面加载完成后立即执行。在你的应用代码中,这是唯一引用 Service Worker 的地方。

下面是我们的 Service Worker 文件。

1
2
3
4
5
6
7
8
9
// serviceworker.js

self.oninstall = function() {
caches.open('fayeFrontEndV1').then(function(cache) {
cache.addAll([ / ... / ])
.catch( / ... / );
})
.catch( / ... /)
}

这些就是安装 Sercice Worker 时执行的代码。首先我们初始化并打开 cache。我们在这里将文件缓存到用户机器上。

caches.open 返回一个包含我们打开的 cache 的引用的 promise。然后我们传给 addAll 函数一个字符串数组。这些字符串是我们要添加到缓存的文件的路径。最后我们添加几个 catch 函数来处理可能会出现的错误。

下一步是 activate:

1
2
3
4
// serviceworker.js
self.onactivate = function(event) {
console.log('sw is up and running!');
}

此时是进行垃圾清理的好时机,不过我们将在另一篇博文里讲解。

最后,也是最棒的部分!让我们来看看 fetch。

1
2
3
4
5
6
7
8
9
10
11
12
13
// serviceworker.js
self.onfetch = function(event) {
event.respondWith(
caches.match(event.request)
.then(function(cachedFiles) {
if(cachedFiles) {
return cachedFiles;
} else {
return fetch(event.request);
}
})
);
}

这个函数会在 Service Worker 检测到 fetch 请求时执行。它会在全部 cache 中试图找到匹配的请求。如果匹配成功,函数将返回 cache 中的结果。否则 Service Worker 会发送网络请求。

让我们仔细分析一下 event.respondWithcaches.match,这俩都是 Service Worker 专有的。

event.respondWith 让你可以打断 fetch 请求并返回你自己的响应内容。一定要注意必须用这个方法而不是简单的 return 一个返回值,只有这样你拦截的回复才能发送到正确的地方。

caches.match 让你能够搜索 CacheStorage 并找到请求的匹配项。我们向 cache 添加的内容,会被存储到一个栈中,最早添加的在最底部,最后添加的在顶部。caches.match 会返回最新的匹配项。如果没有匹配项,则返回 null。

大功告成!以上就是一个简单的 Service Worker 的全部内容!如果你觉得 Service Worker 超级酷,我推荐你了解一下它还能做什么,包括后台 fetch,在这篇博客中

如果你想学习更多关于 Service Worker 的知识,我希望你能去 serviceworkerbook.com 并订阅我的邮件列表,并在 Twitter 关注我!你会在我的书 “Let’s Take This Offline” 出版的第一时间获悉!

「译」Web Components:入门到精通 (1) 「译」动手实现一个单文件 Web Components
广告: