从 10 多秒到 1.05 秒!前端性能优化实践( 四 )


再来看看 service worker 能做些什么:

  • 后台消息传递
  • 网络代理,转发请求,伪造响应
  • 离线缓存
  • 消息推送
  • ...
本文主要以(lishaoy.net)资源缓存为例,阐述下 service worker如何工作 。
2、生命周期
service worker 初次安装的生命周期,如图 :
从 10 多秒到 1.05 秒!前端性能优化实践

文章插图
 
从上 图可知,service worker 工作的流程:
  1. 安装: service worker URL 通过 serviceWorkerContainer.register() 来获取和注册 。
  2. 激活: 当 service worker 安装完成后,会接收到一个激活事件(activate event) 。 onactivate 主要用途是清理先前版本的 service worker 脚本中使用的资源 。
  3. 监听: 两种状态
  4. 终止以节省内存;
  5. 监听获取 fetch 和消息 message 事件 。
  6. 销毁: 是否销毁由浏览器决定,如果一个 service worker 长期不使用或者机器内存有限,则可能会销毁这个 worker  。
Tips:激活成功之后,在 Chrome 浏览器里,可以访问 chrome://inspect/#service-workers和 chrome://serviceworker-internals/ 可以查看到当前运行的service worker ,如图 :

从 10 多秒到 1.05 秒!前端性能优化实践

文章插图
 
现在,我们来写个简单的例子。
3、注册 service worker
要安装 service worker ,你需要在你的页面上注册它 。这个步骤告诉浏览器你的 service worker 脚本在哪里 。
if ('serviceWorker' in navigator) {  navigator.serviceWorker.register('/sw.js').then(function(registration) {    // Registration was successful    console.log('ServiceWorker registration successful with scope: ',    registration.scope);  }).catch(function(err) {    // registration failed :(    console.log('ServiceWorker registration failed: ', err);  });}上面的代码检查 service worker API 是否可用,如果可用, service worker/sw.js被注册 。如果这个 service worker 已经被注册过,浏览器会自动忽略上面的代码 。
4、激活 service worker
在你的 service worker 注册之后,浏览器会尝试为你的页面或站点安装并激活它 。
install 事件会在安装完成之后触发 。install 事件一般是被用来填充你的浏览器的离线缓存能力 。你需要为 install 事件定义一个 callback ,并决定哪些文件你想要缓存.
// The files we want to cachevar CACHE_NAME = 'my-site-cache-v1';var urlsToCache = [  '/',  '/css/main.css',  '/js/main.js'];self.addEventListener('install', function(event) {  // Perform install steps  event.waitUntil(    caches.open(CACHE_NAME)      .then(function(cache) {        console.log('Opened cache');        return cache.addAll(urlsToCache);      })  );});在我们的 install callback 中,我们需要执行以下步骤:
  • 开启一个缓存
  • 缓存我们的文件
  • 决定是否所有的资源是否要被缓存
上面的代码中,我们通过 caches.open 打开我们指定的 cache 文件名,然后我们调用 cache.addAll并传入我们的文件数组 。这是通过一连串 promise (caches.open 和 cache.addAll) 完成的 。event.waitUntil 拿到一个 promise 并使用它来获得安装耗费的时间以及是否安装成功 。
5、监听 service worker
现在我们已经将你的站点资源缓存了,你需要告诉 service worker 让它用这些缓存内容来做点什么 。有了 fetch 事件,这是很容易做到的 。
每次任何被 service worker 控制的资源被请求到时,都会触发 fetch 事件,我们可以给 service worker 添加一个 fetch 的事件监听器,接着调用 event 上的 respondWith() 方法来劫持我们的 HTTP 响应,然后你就可以用自己的方法来更新他们 。
self.addEventListener('fetch', function(event) {  event.respondWith(    caches.match(event.request);  );});caches.match(event.request) 允许我们对网络请求的资源和 cache 里可获取的资源进行匹配,查看是否缓存中有相应的资源 。这个匹配通过 url 和 vary header 进行,就像正常的 HTTP 请求一样 。


推荐阅读