抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

MDN

什么是ServiceWorker

博客serviceworker的在浏览器
ServiceWorker是一种特殊的WebWorker,是在主线程外的另一个独立的线程,通常用作大量计算任务的后台进程。
ServiceWorker于2014年5月由W3C草案定义,它的前身是Application Cache。
博客serviceworker的工作逻辑
在页面请求中,ServiceWorker会根据条件选择使用缓存或者请求新的资源。

ServiceWorker特性

  • 不能直接访问/操作 Dom
  • 需要时直接唤醒,不要时自动休眠
  • 离线缓存内容开发者可控
  • 除非手动卸载,不然永远存活
  • 必须在Https(除本地环境)下工作
  • 大量使用了Promise

    初识ServiceWorker

    判断是否支持ServiceWorker

    if ('serviceWorker' in navigator) {
    console.log('支持ServiceWorker');
    } else {
    console.log('不支持ServiceWorker');
    }
    

    注册ServiceWorker

    假设工作目录为:
    .
    ├─sw.js
    └test.html
    
    window.addEventListener('load', function () {
      // 建议在load事件中执行,因为过早的执行会导致页面加载速度过慢
      this.navigator.serviceWorker.register('sw.js', { scope: '/corss/' })
      // 第一个参数为sw文件路径,第二个参数为配置对象(scope,type,updateViaCache)
      // scope:设置sw可调用文件的范围,默认为父级目录。此处意为只能调用https://::/corss/*下的文件。
          .then(function (registration) {
              console.log("Service Worker注册成功!");
          })
          .catch(function (err) {
              console.log(err);
          })
    })
    
  • 请注意:Service Worker不能“越域”,但除下面的情况外。

如果注册的域远程服务器返回的Service Worker允许工作的最大的域,注册也会成功。
博客serviceworker跨域注册

  • 只要注册的scope不一样,在同一域下允许注册多个不同的scope的service worker

ServiceWorker安装(install)事件

在Service Worker注册成功后,在被注册的sw.js文件中,会存在全局变量selfthis(它俩是同一个对象),可以通过selfthis甚至不写来访问Service Worker对象。
假设工作目录为:

.
├─sw.js
├─test.html
└─test.css
└test.js

监听install事件,并且缓存文件。

<!-- test.html -->
...
<body>
  <script>
    navigator.serviceWorker.register('sw.js');
    </script>
</body>
...
// sw.js
addEventListener('install', function (event) {
    event.waitUntil(
        // waitUntil将会使程序视为已经安装完成,但会等待所有的缓存都完成后再真正安装。
        // 这确保了程序可以在缓存完成之前就可以使用。
        caches.open('sw-cache')
            // 使用全局注册的caches开辟一个名为sw-cache的缓存空间
            .then(function (cache) {
                // 开辟成功,拿到名为cache的缓存空间
                return cache.addAll([
                    './',
                    './test.js',
                    './test.css',
                ]);
                // 将需要缓存的资源添加到缓存空间
            })
            .catch(function (err) {
                // 开辟失败
                console.log(err);
            })
    );
});

缓存完毕后在浏览器应用程序->缓存存储->sw-cache(创建的缓存空间名)中会看到缓存的资源。
博客serviceworker在浏览器的缓存空间

ServiceWorker激活(activate)事件

激活事件会在缓存完毕后触发,可以在激活事件中执行一些操作。
例如删除旧的缓存。
假设工作目录为:

.
├─sw.js
├─test.html
└─test.css
└test.js

监听install事件,并且缓存文件。

<!-- test.html -->
...
<body>
  <script>
    navigator.serviceWorker.register('sw.js');
    </script>
</body>
...
// sw.js
addEventListener('activate', function (event) {
    event.waitUntil(Promise.all([
        // 异步操作
        clients.claim(),
        // 由于service worker初始不会被调用,所以需要手动调用claim方法使其立即生效
        caches.keys().then(function (keys) {
            // 获取所有缓存空间名称
            return Promise.all(keys.map(function (key) {
                if (key !== 'sw-cache') {
                    // 如果缓存空间名称不是sw-cache,则删除
                    return caches.delete(key);
                }
            }));
        }),
    ]))
})

以上代码会删除所有缓存空间名称不是sw-cache的缓存空间。
博客serviceworker在删除缓冲前
博客serviceworker在删除缓冲后

ServiceWorker浏览器支持情况

博客serviceworker在浏览器支持情况

评论