前言
本文是基于项目优化接入Service Worker(后续简写为sw)工具来讲述workbox-webpack-plugin插件的接入使用,对于Service Worker的基础内容不会详细讲解,如想了解,可参考:developer.mozilla.org/zh-CN/docs/… developers.google.com/web/fundame…
基本概念
Service Worker 概念
说明
- Service Worker 是浏览器在后台独立于网页运行的脚本,它打开了通向不需要网页或用户交互的功能的大门。
- 它本质上充当 Web 应用程序、浏览器与网络(可用时)之间的代理服务器。这个 API 旨在创建有效的离线体验,它会拦截网络请求并根据网络是否可用采取来适当的动作、更新来自服务器的的资源。它还提供入口以推送通知和访问后台同步 API。
【注意】:Service worker运行在worker上下文,因此它不能访问DOM。相对于驱动应用的主JavaScript线程,它运行在其他线程中,所以不会造成阻塞。它设计为完全异步,同步API(如XHR和localStorage (en-US))不能在service worker中使用
先决条件
1、浏览器支持
- Service Worker 受 Chrome、Firefox 和 Opera 支持。 Microsoft Edge 现在表示公开支持。可以在 is Serviceworker ready 上查看所有浏览器的支持情况
2、HTTPS
-
在开发过程中,可以通过
localhost
使用 Service Worker,但如果要在网站上部署 Service Worker,则需要在服务器上设置 HTTPS。 -
使用服务工作线程,您可以劫持连接、编撰以及过滤响应。 这是一个很强大的工具。 您可能会善意地使用这些功能,但中间人可会将其用于不良目的。 为避免这种情况,可仅在通过 HTTPS 提供的页面上注册 Service Worker,如此我们便知道浏览器接收的 Service Worker 在整个网络传输过程中都没有被篡改。
生命周期
- 当使用方法
navigator.serviceWorker.register
注册一个新的ServiceWorker时,浏览器会下载JS脚本,解析脚本。这时ServiceWorker处于installing
状态。如果安装成功,则进入installed
状态,否则会进入redundant
状态。 - ServiceWorker成功安装后便进入
installed
状态。至此Service完成了安装过程
,等待进入激活过程
。 - ServiceWoker安装成功后进入
activating
状态。 activated
这时ServiceWorker可以控制页面了,可以监听功能事件了,如fetch,push事件。默认情况下ServiceWorker只能控制在其激活成功后才加载完成的页面redundant
状态是ServiceWorker的终态
workbox-webpack-plugin 概念
workbox-webpack-plugin 介绍
Workbox 提供了两个webpack插件:一个为您生成完整的 Service Worker,另一个生成要预缓存的资产列表,并注入到 Service Worker 文件中。
插件在workbox-webpack-plugin
模块中实现为两个类,named GenerateSW
和InjectManifest
. 具体介绍可以参考 developers SW;
workbox-webpack-plugin 接入
1、安装
npm i --save workbox-webpack-plugin
2、在webpack中使用 GenerateSW
【注意】:
- swDest 必须与index.html处于同一目录下,因为生成的servicework文件只能去匹配该目录下的子目录文件;
- clientsClaim Service Worker 被激活后使其立即获得页面控制权
- skipWaiting 强制等待中的 Service Worker 被激活
- runtimeCaching属性配置:
- urlPattern 匹配的正则规则
- handler属性是以何种方式缓存
-
'CacheFirst' :本地缓存优先
-
'CacheOnly' :只支持缓存
-
'NetworkFirst':网络优先
-
'NetworkOnly' :支持网络
-
'StaleWhileRevalidate':网络与缓存并行
-
5.buildConfig.VERSION 是一个时间戳,代表sw生成的版本,后续业务代码中获取sw文件也是通过VERSION来获取
3.注册service worker
【注意】:
- 由于正式环境访问的是gaems开头的域名url地址,但是接口访问的是deo开头的域名,但serviceworker必须在同域下进行缓存操作,所以需要保证同域相同
- 由于serviceworker是持久缓存,开发过程如果使用,会出现代码/接口数据发生更改,但是页面仍然获取到的是之前已经缓存的数据,所以为了避免该事件产生,只有在NODE_ENV === ‘production’时才会进行注册
- 如果url含有sw参数,就代表不需要使用serviceworker,便于调试
- 如果servicerworker存在,但是不触发的情况,需要将浏览器中存在的serviceworker注销
- 一旦注册成功以后,会将
window.SERVICE_WORKER
设置为true,标志着注册成功
4.接入成功的效果
可以看到访问的静态资源和其他资源都是优先从serviceworker 获取
sw.js js实现
前面的实现是通过workbox封装好的webpack-plugin自动生成的,那么它的js是如何实现的呢?
参考文件
Workbox 3:Service Worker 可以如此简单:fed.taobao.org/blog/taofed…
Service Worker API: developer.mozilla.org/zh-CN/docs/…
Service Worker 介绍developers.google.com/web/fundame…