海灵 · 文章导读✦
导读已播放完成感谢你的聆听 ♥
听一听这篇文章
导读目录 (5)01 / 05
AI
先说结论
海灵提示:吹着海风喝口茶,一起认识下运行在主线程外的后台进程ServiceWorker吧。它具有无法直接操作DOM、自动休眠及离线缓存等特性。我们可以在判断浏览器支持后注册它,通过监听安装事件开辟缓存空间并添加静态资源,接着在激活事件中清理不需要的旧缓存,从而实现对网页离线缓存的精准控制。
MDN
什么是ServiceWorker

ServiceWorker是一种特殊的WebWorker,是在主线程外的另一个独立的线程,通常用作大量计算任务的后台进程。
ServiceWorker于2014年5月由W3C草案定义,它的前身是Application Cache。
在页面请求中,ServiceWorker会根据条件选择使用缓存或者请求新的资源。
ServiceWorker特性
- 不能直接访问/操作 Dom
- 需要时直接唤醒,不要时自动休眠
- 离线缓存内容开发者可控
- 除非手动卸载,不然永远存活
- 必须在**Https(除本地环境)**下工作
- 大量使用了Promise
初识ServiceWorker
判断是否支持ServiceWorker
if ('serviceWorker' in navigator) { console.log('支持ServiceWorker'); } else { console.log('不支持ServiceWorker'); }
|
注册ServiceWorker
假设工作目录为:
window.addEventListener('load', function () { this.navigator.serviceWorker.register('sw.js', { scope: '/corss/' }) .then(function (registration) { console.log("Service Worker注册成功!"); }) .catch(function (err) { console.log(err); }) })
|
- 请注意:Service Worker不能**“越域”**,但除下面的情况外。
如果注册的域在远程服务器返回的Service Worker允许工作的最大的域,注册也会成功。

- 只要注册的scope不一样,在同一域下允许注册多个不同的scope的service worker。
ServiceWorker安装(install)事件

在Service Worker注册成功后,在被注册的sw.js文件中,会存在全局变量self和this(它俩是同一个对象),可以通过self或this甚至不写来访问Service Worker对象。
假设工作目录为:
. ├─sw.js ├─test.html └─test.css └test.js
|
监听install事件,并且缓存文件。
... <body> <script> navigator.serviceWorker.register('sw.js'); </script> </body> ...
|
addEventListener('install', function (event) { event.waitUntil( caches.open('sw-cache') .then(function (cache) { return cache.addAll([ './', './test.js', './test.css', ]); }) .catch(function (err) { console.log(err); }) ); });
|
缓存完毕后在浏览器应用程序->缓存存储->sw-cache(创建的缓存空间名)中会看到缓存的资源。

ServiceWorker激活(activate)事件
激活事件会在缓存完毕后触发,可以在激活事件中执行一些操作。
例如删除旧的缓存。
假设工作目录为:
. ├─sw.js ├─test.html └─test.css └test.js
|
监听install事件,并且缓存文件。
... <body> <script> navigator.serviceWorker.register('sw.js'); </script> </body> ...
|
addEventListener('activate', function (event) { event.waitUntil(Promise.all([ clients.claim(), caches.keys().then(function (keys) { return Promise.all(keys.map(function (key) { if (key !== 'sw-cache') { return caches.delete(key); } })); }), ])) })
|
以上代码会删除所有缓存空间名称不是sw-cache的缓存空间。


ServiceWorker浏览器支持情况
