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

service-worker实践的更多相关文章

  1. Service Worker

    Service Worker 随着前端快速发展,应用的性能已经变得至关重要,关于这一点大佬做了很多统计.你可以去看看. 如何降低一个页面的网络请求成本从而缩短页面加载资源的时间并降低用户可感知的延时是 ...

  2. 转《service worker在移动端H5项目的应用》

    1. PWA和Service Worker的关系 PWA (Progressive Web Apps) 不是一项技术,也不是一个框架,我们可以把她理解为一种模式,一种通过应用一些技术将 Web App ...

  3. service worker在移动端H5项目的应用

    1. PWA和Service Worker的关系 PWA (Progressive Web Apps) 不是一项技术,也不是一个框架,我们可以把她理解为一种模式,一种通过应用一些技术将 Web App ...

  4. service worker介绍

    原文:Service workers explained 译者:neal1991 welcome to star my articles-translator, providing you advan ...

  5. [PWA] 9. Service worker registerion && service work's props, methods and listeners

    In some rare cases, you need to ask user to refresh the browsser to update the version. Maybe becaus ...

  6. [PWA] 2. Service worker life cycle

    Once serive worker is registered, the first time we go to the app, we cannot see the logs from servc ...

  7. [PWA] 1. Intro to Service worker

    Service worker stays between our browser and noetwork requests. It can help to fetch data from cache ...

  8. Service Worker和HTTP缓存

    很多人,包括我自己,初看Service Worker多一个Cache Storage的时候,就感觉跟HTTP长缓存没什么区别. 例如大家讲的最多的Service Worker能让网页离线使用,但熟悉H ...

  9. Service Worker基础知识整理

    Service Worker是什么 service worker 是独立于当前页面的一段运行在浏览器后台进程里的脚本.它的特性将包括推送消息,背景后台同步, geofencing(地理围栏定位),拦截 ...

  10. Service Worker MDN英文笔记

    前言: 以前学习基础知识的时候总看别人写的入门文章,但有时候还是一脸懵逼,直到自己用心阅读了MDN的英文文档才对基础知识的一些理论有了更深的理解,所以我在边阅读文档的时候边记录下帮助比较大的,也方便大 ...

随机推荐

  1. 从零开始的全栈工程师——js篇2.11(原型)

    原型 原型分析 1.每个 函数数据类型(普通函数,类)都有一个prototype属性 并且这个属性是一个对象数据类型2.每个Prototype上都有一个constructor属性 并且这个属性值是当前 ...

  2. springBoot jpa uuid生成策略

    实体类 import org.hibernate.annotations.GenericGenerator; import javax.persistence.*; @Entity @Table(na ...

  3. Ubuntu 16.04 远程登入root 用户

    安装 open ssh: sudo apt-get install openssh-server   修改 root 密码 sudo passwd root   以其他账户登录,通过 sudo nan ...

  4. Windows 10 下使用Git

    事实上,比在Linux下要难很多.不仅仅是因为Linux下CMD功能较弱,还有就是国内的网络环境,至少,我这Github Windows安装时,总是会下载无法完成 Github Desktop 虽然, ...

  5. HDU汉诺塔系列

    这几天刷了杭电的汉诺塔一套,来写写题解. HDU1207 汉诺塔II HDU1995 汉诺塔V HDU1996 汉诺塔VI HDU1997 汉诺塔VII HDU2064 汉诺塔III HDU2077  ...

  6. 用户在设置密码时,提醒请输入半角字符(vue+element+valid)

    要保证callback()只有一个出口 rules:{ newPassword: [{validator:(rule,newPassword,callback)=>{ var all = fal ...

  7. MVC文件下载和webform也能使用的下载方法

    public ActionResult Index() { DownloadMethod("text/plain", "C:/Users/sunny/Pictures/S ...

  8. vuejs属性绑定和双向绑定

    属性绑定 html <div v-bind:title="title">hello world</div> js new Vue({ el:'#root', ...

  9. CSS之常见文字样式整理

    常见文字样式 行高:line-height,当我i们将行高的大小设置成当前元素的高度时,可以实现当行文本在当前元素中垂直方向居中显示的效果 水平对齐方式:text-align:left|center| ...

  10. java基础面试题:如何把一段逗号分割的字符串转换成一个数组? String s = "a" +"b" + "c" + "d";生成几个对象?

    package com.swift; public class Douhao_String_Test { public static void main(String[] args) { /* * 如 ...