service-worker虽然已列入标准,但是支持的浏览器还是有限制,还有比较多的问题。

1. 生命周期

注册成功-------installing--------------> 安装成功(installed)(waiting) ---------activating----------> 激活成功 (activated)------> 销毁(redundant)
其中任何一个步骤失败都将进入销毁(redundant)
a. 注册:

调用 navigator.serviceWorker.register 方法,第一个参数是 service-worker对应的js文件, 第二个参数可选,scope是表示 service-worker 的作用域,最大的作用域就是 service-worker.js所在目录。

这2个参数都相对于origin目录,而不是项目根目录。

比如 https://mdn.github.io/sw-test/sw.js ,项目根目录是 https://mdn.github.io/sw-test/,路径应该写成 /sw-test/sw.js 而非 /sw.js.

不写scope默认就是最大的作用域,{scope: '/service-worker/foo/'} 表示service-worker只在foo目录下生效,一定要保证当前sw是最新的且没有被之前sw控制的页面,否则没效果。

navigator.serviceWorker.('/service-worker/service-worker.js', {scope: '/service-worker/foo/'})
.then(function (registration) {
console.log('registration:',registration);
})
.catch(function (e) {
console.error(e);
})

b. 安装

注册成功后进入installing状态,这时会触发 install 事件, 在这个事件里面我们可以添加文件到缓存,如果不调用 skipWaiting 当前sw会在安装成功后进入waiting状态,直到所有页面都没有被旧的sw控制为止。

调用skipWaiting 将使当前sw直接进入 activating 状态。在开发调试时最好设置skipWaiting ,否则刷新页面新的sw一直处于waiting而不被使用。

self.addEventListener('install', function (event) { //  监听worker的install事件
self.skipWaiting();//让新 SW 立即激活。这里不会跳过 installing, 只会等安装成功后跳过 waiting直接将之前存在的sw销毁,新的sw进入到activating
event.waitUntil( // 延迟install事件直到缓存初始化完成
caches.open(CACHE_VERSION)
.then(function (cache) {
console.log('Opened cache');
return cache.addAll(CACHE_FILES); // 会从网络加载需要缓存的文件,这时当前sw的fetch还没监听
})
);
});

3. 激活

sw从waiting状态进入到 activating 这时会触发 activate 事件, 可以在这个事件里面处理缓存的清理功能,这里要注意 self.clients.claim ,假如页面没有sw控制,这个方法可以让当前页面马上sw控制,在控制之后的请求都会被fetch监听到,如果没有调用这个方法就必须刷新页面或关了页面重新进来页面才会被sw控制。

self.addEventListener('activate', function (event) { // 监听worker的activate事件

    event.waitUntil( // 延迟activate事件直 到
caches.keys().then(function(keys){
return Promise.all(keys.map(function(key, i){ // 清除旧版本缓存
if(key !== CACHE_VERSION){
//console.log(keys, key)
return caches.delete(keys[i]);
}
}))
})
) //When a service worker is initially registered, pages won't use it until they next load. The claim() method causes those pages to be controlled immediately.
self.clients.claim(); //让没被控制的 clients(页面、workers) 受控, 否则要刷新页面才受控,比如资源加载触发fetch(可以设置延时加载模拟)
});

激活成功后进入activated状态,这时fetch、message、put事件被触发。

self.addEventListener('fetch', function(event) {
// Do stuff with fetch events
}); self.addEventListener('message', function(event) {
// Do stuff with postMessages received from document
});

可以利用fetch事件监听资源请求,进行修改响应或请求,发现请求资源没在缓存列表,可以从网络加载资源,并添加到缓存列表

self.addEventListener('fetch', function (event) { //  截取页面的资源请求
console.log('fetching',event.request); //网络请求触发该事件
event.respondWith(
caches.match(event.request).then(function (response) {
if(res){ // 匹配缓存返回缓存中的资源
return res;
}else{
throw new Error();
}
}).catch(function() { //没有在缓存列表,重新请求网络
return fetch(event.request).then(function(response) {
//if not a valid response send the error
if(!response || response.status !== 200 || response.type !== 'basic'){
return response;
}
return caches.open(CACHE_VERSION).then(function(cache) {
cache.put(event.request, response.clone()); //请求的资源添加到缓存
return response; //返回请求的响应
});
});
}).catch(function() {
//请求失败返回默认的资源
return caches.match('/sw-test/gallery/myLittleVader.jpg');
})
);
});

service worker 所涉及的知识比较多,包括cache缓存、promise等。

至于cache能缓存多大的容量,同一域名下的 ServiceWorkerCache 也只能使用 40M,参考:https://zhuanlan.zhihu.com/p/27586862

PWA的核心技术包括:

Web App Manifest – 在主屏幕添加app图标,定义手机标题栏颜色之类
Service Worker – 缓存,离线开发
App Shell – 先显示APP的主结构,再填充主数据,更快显示更好体验
Push Notification – 消息推送

可以参考百度的基于vue的pwa脚手架:https://lavas.baidu.com/

参考文档:

https://developer.mozilla.org/zh-CN/docs/Web/API/Service_Worker_API/Using_Service_Workers

http://www.zhangxinxu.com/wordpress/2017/07/service-worker-cachestorage-offline-develop/

https://segmentfault.com/a/1190000006061528

https://segmentfault.com/a/1190000007487049#articleHeader2

https://zhuanlan.zhihu.com/p/20040372

最新文章

  1. 浅谈Java中的对象和引用
  2. GZFramework.DB.Core初始化
  3. redis 问题解决(MISCONF Redis is configured to save RDB snapshots)
  4. window下查看TCP端口连接情况
  5. BZOJ 1093 最大半连通子图
  6. 关于 mvc 中 连字符 - 和下划线 _转换的问题。
  7. Dialog第三方登录等待
  8. AS【常用插件】
  9. (转)document.cookie.indexof的解释
  10. 是用Epplus生成Excel 图表
  11. JDK的下载,安装与环境的配置
  12. docker 进程监控 Dumb-Init进程信号处理 --转自https://blog.csdn.net/tiger435/article/details/54971929
  13. DIVCNT2&&3 - Counting Divisors
  14. hdu 2588(简单的欧拉
  15. win Apache服务消失或无法启动
  16. mysql字符集说明
  17. 下载外部jar包后,链接源码和javadoc.jar
  18. [转]SharePoint 2010 Powershell Feature Cmdlets
  19. Micro:bit 硬件架构介绍
  20. linux 相关的问题

热门文章

  1. 添加SAP_ALL权限
  2. 适用于 Internet Explorer 11 的企业模式
  3. 如何修改HDFS上文件
  4. 腾讯云服务器手动和自动安装WordPress网站程序
  5. 基于spark Mllib(ML)聚类实战
  6. expect脚本中,变量的写法
  7. theano 模块 MLP示例
  8. 通过jQuery遍历div里面的checkbox
  9. display:inline-block解决文字有间隙问题
  10. python2与python3下的base64模块