是什么?
- 服务器与浏览器的中介
- 持久的浏览器离线缓存
有什么用?
- 解放主线程,节省资源加载,提高浏览体验
其他描述
- 基于web worker,并在其基础上,增加了离线缓存的功能
- 独立于当前网页线程(后台线程)
- 在网页发起请求进行代理,缓存文件(网络代理)
- 必须是https的协议
- 被install后,就永远存在,除非手动卸载
生命周期
具体展现
在Application,能看到该页面是否激活sw
也可以在NetWork,查看具体的接口文件,是否缓存于sw
也可以在Application的Cache Storage中查看缓存的具体内容:
基本使用
1. 注册
通知浏览器分配一块内存
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.register('./serviceworker.js')
.then((reg) => {
console.log('ServiceWorker register success: ', reg)
}).catch((err) => {
console.log('ServiceWorker register failed: ', err)
})
}
sw拥有作用域,会监听该作用域下面代理的代所有请求,
例如我只能想要监听my文件夹,就在注册时指定路径:
navigator.serviceWorker.register('./home/serviceworker.js')
2. 安装
注册后,浏览器就会安装sw,我们可以通过事件监听
// 资源属性
var CACHE_PREFIX = 'cms-sw-cache';
var CACHE_VERSION = '0.0.20';
var CACHE_NAME = CACHE_PREFIX+'-'+CACHE_VERSION;
var ALL_ASSETS = ['./main.css'];
self.addEventListener('install', (event) => {
//用来强制更新的servicework跳过等待时间
self.skipWaiting()
event.waitUntil(
caches.open(CACHE_NAME).then(function (cache) {
return cache.addAll(ALL_ASSETS)
})
)
})
3. 激活
self.addEventListener('activate', (event) => {
var cacheWhitelist = [CACHE_NAME]
// 保证 激活之后能够马上作用于所有的终端
self.clients.claim()
event.waitUntil(
caches.keys().then((cacheNames) => {
return Promise.all(
cacheNames.map((cacheName) => {
if (cacheWhitelist.indexOf(cacheName) === -1) {
return caches.delete(cacheName)
}
})
)
})
)
})
在激活sw时需要删除之前的缓存,可将需要的缓存放在有个白名单中
然后通过caches.keys()拿到所有缓存,将不再白名单中的缓存删掉。
4. 拦截网络请求
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request).then((response) => {
if (response)
return response;
return fetch(event.request);
})
);
});
5. 卸载
navigator.serviceWorker.getRegistrations().then(function (registrations) {
for (let registration of registrations) {
//安装在网页的service worker不止一个,找到我们的那个并删除
if (registration && registration.scope === 'http://localhost:8080/') {
registration.unregister()
}
}
})
总结
在日常迭代项目中,遇到了浏览器缓存的问题,深入研究并发现了sw。
因此本篇文章,仅对于个人对于sw的尝试与学习,初步理解其运用。
进阶文献
网易云课堂 Service Worker 运用与实践
Service Worker简介