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. 利用Cookie保存用户身份信息实现免登录

    <%@page import="sun.misc.BASE64Encoder"%> <%@page import="java.util.Base64.E ...

  2. 学习《CSS选择器Level-4》不完全版

    1 概述 1.1 前言 选择器是CSS的核心组件.本文依据W3C的Selectors Level 4规范,概括总结了Level1-Level4中绝大多数的选择器,并做了简单的语法说明及示例演示.希望对 ...

  3. SpringBoot的核心功能

    1.独立运行的Spring项目 SpringBoot可以以jar包的形式独立运行,运行一个SpringBoot项目只需要通过java -jar xx.jar来启动. 2.内嵌Servlet容器 Spr ...

  4. 一、基于Qt的图像矩形区域改色

    Qt环境下图像的打开和涂色 一.设计目标 能够在 Qt QtCreator 环境下打开常用图像格式文件,诸如 bmp.jpg.png 图像等,然后将他们转化为 Qt 中的 QImage 类,并进行矩形 ...

  5. HDU 2191 悼念汶川地震(多重背包)

    思路: 多重背包转成01背包,怎么转?把一种大米看成一堆单个的物品,每件物品要么装入,要么不装.复杂度比01背包要大.时间复杂度为O(vns)(这里S是所有物品的数量s之和).这个做法太粗糙了,但就是 ...

  6. Python参数基础

    Python参数基础 位置参数 ​ 通过位置进行匹配,把参数值传递给函数头部的参数名称,顺序从左到右 关键字参数 ​ 调用的时候使用参数的变量名,采用name=value的形式 默认参数 ​ 为没有传 ...

  7. java +selenuim使用js显示控件

    操作selenium控件时,往往需要有些控件提前显示,特别是后台的一些控件,或者需要使用鼠标显示下拉的操作,有时鼠标悬停,在点击不怎么好使,就可以依靠js方式,提前让控件显示. 1.使用style的方 ...

  8. fold - 折叠输入行, 使其适合指定的宽度

    总览 (SYNOPSIS) ../src/fold [OPTION]... [FILE]... 描述 (DESCRIPTION) 折叠(wrap) 每个 文件 FILE 中 的 输入行 (缺省为 标准 ...

  9. python_16_自己建立模块

    import python_5_password

  10. vue中的过滤器

    过滤器 过滤器规则 Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化.过滤器可以用在两个地方: 双花括号插值{{}}和 v-bind 表达式 (后者从 2.1.0+ 开始支持).过滤器应 ...