You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
W3C 组织早在 2014 年 5 月就提出过 Service Worker 这样的一个 HTML5 API ,主要用来做持久的离线缓存。
浏览器中的 javaScript 都是运行在一个单一主线程上的,在同一时间内只能做一件事情。随着 Web 业务不断复杂,我们逐渐在 js 中加了很多耗资源、耗时间的复杂运算过程,这些过程导致的性能问题在 WebApp 的复杂化过程中更加凸显出来。
Service Worker 是在新开 Web Worker进程脱离在主线程之外, 将缓存拦截处理完成后通过 postMessage 方法告诉主线程,而主线程通过 onMessage 方法得到 Web Worker 的结果反馈。Service Worker 在 Web Worker 的基础上加上了持久离线缓存能力。
无论是 Service Worker 作用域问题,还是 Service Worker 的更新问题,都与 Service Worker 的注册息息相关,一个看似简单的 Service Worker 的注册还是有很多地方需要注意,但是如果这些都需要在每个项目中都要自己完全实现一遍,还是非常繁琐的。而sw-precache-webpack-plugin 和 sw-register-webpack-plugin 作为一个 Webpack Plugin 很好的帮助我们解决了优雅的注册 Service Worker 的问题
什么是 Service Worker
W3C 组织早在 2014 年 5 月就提出过 Service Worker 这样的一个 HTML5 API ,主要用来做持久的离线缓存。
浏览器中的 javaScript 都是运行在一个单一主线程上的,在同一时间内只能做一件事情。随着 Web 业务不断复杂,我们逐渐在 js 中加了很多耗资源、耗时间的复杂运算过程,这些过程导致的性能问题在 WebApp 的复杂化过程中更加凸显出来。
Service Worker 是在新开 Web Worker进程脱离在主线程之外, 将缓存拦截处理完成后通过 postMessage 方法告诉主线程,而主线程通过 onMessage 方法得到 Web Worker 的结果反馈。Service Worker 在 Web Worker 的基础上加上了持久离线缓存能力。
Service Worker 功能和特性
Service Worker 的伟大使命,就是让缓存做到优雅和极致,让 Web App 相对于 Native App 的缺点更加弱化,也为开发者提供了对性能和体验的无限遐想,其含有很多特性和功能点
Service Worker 浏览器支持情况
Service Worker 浏览器支持情况怎么样呢?参考 Can I use 可得下图:

前支持的浏览器不多,而且支持的浏览器也是在试验阶段,Chrome、Firefox、Opera 支持性较好,同时 x5 andriod 支持 Service Worker
Service Worker 使用限制
Service Worker 除了 work 线程的限制外,由于可拦截页面请求,为了保证页面安全,浏览器端对 Service Worker 的使用限制也不少。
1)service worker 脚本的 URL, 不支持跨域,不允许缓存 service worker 脚本如 service-worker.js。
2)service worker 脚本的 URL, 不支持
Blob/String URL
,Create service worker from Blob/String URL。3)无法直接操作 DOM 对象,也无法访问 window、document、parent 对象。可以访问 location、navigator;
4)可代理的页面作用域限制 (scope) 。默认是 service-worker.js 所在文件目录及子目录的请求可代理,可在注册时手动设置作用域范围;
5)必须在 https 中使用,允许在开发调试的 localhost 使用。
Service Worker 生命周期
Service Worker 的工作原理是基于注册、安装、激活等步骤在浏览器 js 主线程中独立分担缓存任务的,那么我们如何在这些 API 自身一系列的操作中进行一些我们自己想让 worker 干的事情呢?
这里我们需要了解一下 Service Worker 的生命周期的概念,这有利于我们学会在各个生命周期的阶段进行有目的性的回调,让我们自定义的工作在 Service Worker 中正确有效的开展下去。MDN 给出了详细的 Service Worker 生命周期图:
我们可以看到生命周期分为这么几个状态
安装中
,安装后
,激活中
,激活后
,废弃
安装( installing ):这个状态发生在 Service Worker 注册之后,表示开始安装,触发 install 事件回调指定一些静态资源进行离线缓存。
install 事件回调中有两个方法:
event.waitUntil()
:传入一个 Promise 为参数,等到该 Promise 为 resolve 状态为止。self.skipWaiting()
:self 是当前 context 的 global 变量,执行该方法表示强制当前处在 waiting 状态的 Service Worker 进入 activate 状态。安装后( installed ):Service Worker 已经完成了安装,并且等待其他的 Service Worker 线程被关闭。
激活( activating ):在这个状态下没有被其他的 Service Worker 控制的客户端,允许当前的 worker 完成安装,并且清除了其他的 worker 以及关联缓存的旧缓存资源,等待新的 Service Worker 线程被激活。
Service Worker 文件
对于浏览器来说,Service Worker 是一个独立于 js 主线程的一种 Web Worker 线程,一个独立于主线程的 Context,但是面向开发者来说 Service Worker 的形态其实就是一个需要开发者自己维护的文件,我们假设这个文件叫做 service-worker.js,此文件的内容就是定制 Service Worker 生命周期中每个阶段所处理的定制化的细节逻辑,比如缓存 Cache 的读写,更新的策略,推送的策略等等,通常 service-worker.js 文件是处于项目的根目录,并且需要保证能直接通过 https: //yourhost/service-worker.js 这种形式直接被访问到才行。
service-worker.js基本结构代码,如下:
快速注册 Service Worker
注册 Service Worker 还是蛮简单的,只要小段代码。只要在工程中的 html 文档的 <script> 标签里或者随便在页面的哪个 javaScript 模块中添加如下代码即可
sw-register-webpack-plugin 与 sw-precache-webpack-plugin
无论是 Service Worker 作用域问题,还是 Service Worker 的更新问题,都与 Service Worker 的注册息息相关,一个看似简单的 Service Worker 的注册还是有很多地方需要注意,但是如果这些都需要在每个项目中都要自己完全实现一遍,还是非常繁琐的。而sw-precache-webpack-plugin 和 sw-register-webpack-plugin 作为一个 Webpack Plugin 很好的帮助我们解决了优雅的注册 Service Worker 的问题
参考资料:
workbox
Service Worker 简介
如何优雅的为 PWA 注册 Service Worker
Service Worker最佳实践
Progressive Web App 的离线存储
Service Workers 与离线缓存
PWA与service worker工作原理探析
service worker 实现离线缓存
使用service worker对静态资源进行全缓存
PWA 应用实战
The text was updated successfully, but these errors were encountered: