Service Worker初探

本文深入探讨Service Worker的核心功能和优势,包括离线访问、快速加载和离线可用性。详细阐述了其安全策略、使用方法、生命周期、CacheStorage API及其与http缓存的关系。此外,还介绍了基于版本控制的缓存模式、后台同步保证离线功能以及sync事件的数据传递。Service Worker是优化Web应用的关键技术,为开发者提供了强大的离线和性能提升工具。
摘要由CSDN通过智能技术生成

编者按:本文作者王若铮,奇舞团前端开发工程师。

本文是奇舞团泛前端分享会Service Worker初探的一次记录,是对360扫地机器人App内嵌web页面使用Service Worker优化的一次总结。

本文所有代码示例均已提交到github,地址1

Service Worker是什么

Service Worker是渐进式web应用(pwa)的核心技术。

通过注册之后,可以独立于浏览器在后台运行,控制我们的一个或者多个页面。如果我们的页面在多个窗口中打开,Service Worker不会重复创建。

就算浏览器关闭之后,Service worker也同样运行。但是浏览器是不会允许Service Worker一直处于工作状态。因为随着用户打开越来越多的注册了Service Worker的页面,性能肯定会收到影响。在后面的生命周期中,我们会一起探讨Service Worker的运行原理。

Service Worker是客户端和服务端的代理层,客户端向服务器发送的请求,都可以被Service Worker拦截,并且可以修改请求,返回响应。

同时也会在用户离线的时候正常工作,当浏览器发送请求,Service Worker检测到离线状态的时候,可以直接返回缓存数据和提前准备好的离线页面。

进一步来讲,用户关闭了所有的页面,Service Worker同样可以和服务器通信。完成尚未完成的数据请求,可以确保用户的任何操作都可以发送到服务器。

Service Worker的优势

1. 支持离线访问

传统的web页面,在每次访问的时候,都会去请求服务器的资源。在使用Service Worker之后,第一次访问的时候,可以将我们的静态资源缓存下来,下次访问的时候可以通过Service Worker返回缓存,就可以支持离线访问了。

2. 加载速度快

页面资源缓存之后,不需要依赖网络加载服务器资源。无论用户是否具有良好的的网络状态,甚至在离线的情况下,都可以瞬间加载我们的web页面。

3. 离线状态下的可用性

在不追求返回结果的数据请求中,可以使用Service Worker进行代理。当客户端从离线转为在线的时候,就算已经关闭了页面。Service Worker也能够帮助我们继续发送代理的请求。无论,用户是在线、离线还是网络不稳定的时候,借助Service Worker都能够提供一个相对完整的用户体验。

安全策略

由于serviceworker功能强大,可以修改任何通过它的请求,因此需要对其进行一定的安全限制。

1. 使用https或者localhost本地域名的页面才可以使用Service Worker

正常情况下,只有使用https的页面才能够注册Service Worker。为了方便我们的开发和调试,在开发的过程中,可以使用localhost来使用Service Worker。一旦把应用部署到服务器之后,必须使用https保证Service Worker的正常工作。

2. Service Worker的作用域

每个Service Worker都有一个有限的控制范围。这个范围就是通过放置Service Worker的js文件的目录决定的,也就是Service Worker所在目录以及所有的子目录。

也可以通过注册Service Worker的时候传入一个scope选项,用来覆盖默认的作用域。但是,只能将作用域的范围缩小,不能将它扩大。换句话来说,scope的值,必须是Service Worker所在目录或者是子目录。

navigator.serviceWorker.register('serviceworker.js', { scope: '/' })

如何使用

下面我们根据一个简单的示例,看一下Service Worker是如何运行的。

在浏览器环境下,我们可以通过navigator.serviceWorker.register注册一个Service Worker。register方法的第一个参数是Service Worker的js文件的地址,第二个参数是规定了Service Worker的作用域。

window.onload = function() {
    if ('serviceWorker' in navigator) {
      navigator.serviceWorker.register('./serviceworker.js', { scope: '/' })
    }
  }

注册之后,Service Worker可以独立于浏览器在后台运行,来控制我们的页面。如果我们的页面在多个窗口中打开,Service Worker不会重复创建,在不同窗口中的页面,均由一个Service Worker统一管理。

下面我们创建一下serviceworker.js文件。

在这里,监听了两个事件。在install事件中,我们将一个离线页面缓存进来。在fetch事件中,如果资源请求失败的话,使用刚才缓存的离线页面。这样,我们的web应用就会在离线状态下,加载这个离线页面了。

self.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open('cache').then((cache) => {
      return cache.add('./offline.html')
    })
  )
})
self.addEventListener('fetch', function(event) {
  event.respondWith(
    fetch(event.request).catch(() => {
      return caches.match('./offline.html')
    })
  )
})

请注意,我们刚刚提到过Service Worker的安全策略只允许我们在Https或者localhost下注册它,所以我们一定要开启一个本地服务器来运行我们的代码示例。

下面,我们对于刚才的例子做一个小小的改动。我们新建一个new_offline.html文件,将serviceworker.js中的offline.html替换为new_offline.html。如果你刚才已经运行过上一版的代码,你就会发现,页面并没有发生改变,在离线状态下,页面依然是旧版的offline.html。

当我们关闭所有运行代码的标签页之后再次打开,我们就会惊奇的发现,页面更新了。想要搞明白这些问题,我们必须要了解Service Worker的生命周期。

生命周期

在注册Service Worker之后,Service Worker会马上进去installing的生命周期进行安装,同时会进入Service Worker的install事件中。如果在installing中,有任何资源加载失败,都会导致安装失败,Service

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值