ServiceWorker 缓存与 HTTP 缓存

1,767 阅读4分钟

image 之前做性能优化分享,提到过缓存是很重要的一环。现在主流的缓存基本都是 HTTP 缓存,像 ServiceWorker 缓存用的少之又少。今天来聊一聊,ServiceWorker 是什么 ? 与 HTTP 缓存哪个更快?首先来了解一下概念性的东西

ServiceWorker

服务器与浏览器之间的中间人,如果网站中注册了Service Worker那么它可以拦截当前网站所有的请求,进行判断(需要编写相应的判断程序),如果需要向服务器发起请求的就转给服务器,如果可以直接使用缓存的就直接返回缓存不再转给服务器,我们在Service Worker 中可以做拦截客户端的请求、向客户端发送消息、向服务器发起请求等先关操作,其中最重要且广泛的的作用就是离线资源缓存。 image.png

特性

  1. 基于web worker
  2. 在web worker的基础上增加了离线缓存的能力
  3. 本质上充当Web应用程序(服务器)与浏览器之间的代理服务器
  4. 创建有效的离线体验(将一些不常更新的内容缓存在浏览器,提高访问体验)
  5. 由事件驱动的,具有生命周期
  6. 可以访问cache和indexDB
  7. 支持消息推送
  8. 并且可以让开发者自己控制管理缓存的内容以及版本
  9. 可以通过 postMessage 接口把数据传递给其他 JS 文件

兼容

2021-09-06T02:04:18.png

缓存策略

image.png

在浏览器体现

当我们的应用的用了 servicework, 我们打开network里面的 js 可以发现, 会有标识 image.png 当我们命中缓存策略的时候,就会发起一个 fetch 请求,开始从本地webworker 拉取请求,从而实现缓存功能 然后这个时候也可以打开 Application 来观察

image.png image.png

生命周期

Service Worker 生命周期

  1. 在主线程成功注册 Service Worker 之后,开始下载并解析执行 Service Worker 文件,执行过程中开始安装 Service Worker,在此过程中会触发 worker 线程的 install 事件。


  2. 如果 install 事件回调成功执行(在 install 回调中通常会做一些缓存读写的工作,可能会存在失败的情况),则开始激活 Service Worker,在此过程中会触发 worker 线程的 activate 事件,如果 install 事件回调执行失败,则生命周期进入 Error 终结状态,终止生命周期。


  3. 完成激活之后,Service Worker 就能够控制作用域下的页面的资源请求,可以监听 fetch 事件。


  4. 如果在激活后 Service Worker 被 unregister 或者有新的 Service Worker 版本更新,则当前 Service Worker 生命周期完结,进入 Terminated 终结状态。

了解了基础原理以后让我们进入实战阶段吧

实战

  1. 注册实例 image.png
  2. 编写sw.js 也就是要缓存的内容 image.png 可以看到这里, 我们针对 cdn 的东西走的缓存策略是 cacheOnly, 意思就是只走缓存 由于编写原生的 sw.js 比较复杂,且要写大量正则,这里的示例我们用了谷歌的 servicework 框架 workbox。它有配套的 workbox-webpack-plugin 可以轻松让我们在 vue 的项目中实现 service-worker

对照实验

前面讲了这么多 sw 的基本介绍,那么它跟传统的 http 缓存谁更快呢首先看来看缓存位图 image.png MemoryCache 作为老大哥,位于 ServiceWorker 之上。 也就是命中了 MemoryCache,就不会触发 ServiceWorker 的 fetch 事件

MemoryCache、DiskCache、ServiceWorker 缓存哪个速度更快?

让我们来看国外的一组数据对照 image.png image.png image.png image.png

这样看我们发现,sw 岂不是没啥用,反而拖累了网站的加载速度?

带着这个疑惑,我们试试大量的资源情况下

实验2: 100张图片对照

image.png 当我把并发图片增加到 100 张,sw 后来居上了,但是依然好奇为什么 DiskCache 为什么在第一次试验中比 ServiceWorker Cache 更快? 观察:

  1. DiskCache:排队依然是问题,且随着并发数成线性上升。我们甚至能看到浏览器是如何加载图片的,一次并发大概 6 张图片。

  2. ServiceWorker Cache:虽然等待时间随着并发数上升,但是是平缓的。

结论:大并发下 ServiceWorker Cache 比 DiskCache 更快。

总结

在某些时候,在少量资源情况下 ServiceWorker 确实不如 HTTP 缓存,但是ServiceWorker 的用途会更加广泛,它提供了更细力度的缓存控制、使离线化应用得以实现、并且对比主线程,他能够使用更多的 CacheAPI 容量。

哪些伙计在用

image.png