ServiceWorker 介绍

ServiceWorker 是一种特殊的 Worker,处理与网页资源相关的逻辑,充当浏览器与服务器之间的代理,用于离线请求和性能优化。本文详细介绍了 Cache 的基础用法、匹配逻辑和容量,ServiceWorker 的作用范围、客户端、生命周期,以及 Workbox 框架的策略和插件。此外,还讨论了 ServiceWorker 的潜在风险和紧急移除方法,提供了ServiceWorker 入口文件缓存方案。
摘要由CSDN通过智能技术生成

 

引言

我们经常可以听到 Worker 这个名词,比如本文要介绍的 ServiceWorker 后面就带着一个 Worker 的单词,那么 Worker 实际上指的是什么呢?

在介绍 Worker 的定义之前,先来回忆一下浏览器的渲染原理。

在一个 tab 打开的时候,浏览器会给这个 tab 创建一个新的渲染进程(renderer process),如下图:


在每一个渲染进程中,都会有一个主线程(Main Thread),负责 JavaScript 的执行以及浏览器的渲染(JavaScript 的执行与 UI 渲染是一个互相阻塞的流程)。

如果 JavaScript 执行时间过久(比如超过 33.33 ms),那么一帧内留给 UI 渲染的时间不多,如果这时候网页有正在执行的动画,那么用户就会感受到卡顿。

10 FPS:能够达成基本的视觉残留(参考:定格动画至少需要 12 帧每秒以上)

30 FPS以下:让人感觉到明显的卡顿和不适感

30-50 FPS:因人而异

50-60 FPS:流畅

一个 Worker,指的是一个可以在后台独立执行 JavaScript 脚本。它存在于一个单独的 worker 线程,即使执行一些长任务也不会阻塞主线程响应用户操作(如鼠标点击、动画等)。

另外 Worker 也指使用 new Worker() 构造函数创建的一个对象,可以用在主线程与 worker 线程的通信


 

 Worker 与 主线程之间可以通过 postMessage 进行通信:

 

worker 线程与主线程通信方式

Worker 一般有其独立的上下文:WorkerGlobalScope,其全局变量一般用 self 来表示,如果使用 window 则会报错

ServiceWorker 介绍

本文要介绍的 ServiceWorker 是一种特化的 Worker,专门来处理跟网页有关的资源(assets),在浏览器和真正的服务端之间扮演一个代理(Proxy)的角色。ServiceWorker 同时引入了缓存(Cache),可以用来存储一个网络响应。

下文会继续介绍 Cache 相关的知识。


图:ServiceWorker 中重要的几个角色

一般来说,ServiceWorker 处理的就是页面与缓存、服务器之间的关系(下文有详细介绍)。

ServiceWorker 的出现是为了解决下面的两个问题:

  • 离线请求(提供类似于 App 的用户体验,类 App 的生命周期)
  • 性能优化

Cache

由于 ServiceWorker 是一种特化型 Worker,它专门处理资源相关的逻辑,简单来说就是做一些缓存(但不止与此),下面先介绍一下 ServiceWorker 做缓存用到的一个底层 API:Cache

Cache 提供一个Request -> Response的持久缓存,除非显式删除,存储在 Cache 里面的数据不会主动过期,同时也不会主动去更新,需要手动维护其更新。


 

 

图:Cache 存储的是 Request -> Response 的键值对

Cache 基础用法

一个域之内可以存在多个 Cache,可以通过一个名字来标识对应的 Cache:

可以通过 CacheStorage 来获取对应 Cache 对象,有同源策略

// caches extends CacheStorage,是 window / self 上面的一个全局变量
// 下面是通过一个 cacheName 来获取对应的缓存对象
const cache = await caches.open('hello-cache-v1');

然后可以通过 Cache.put 方法将缓存设置进去

 

const request = new Request('/samples/service-worker/basic/', { method: 'GET' })
const response = await fetch(request)
const cache = await caches.open('hello-cache-v1');
cache.put(request, response)

结果如下:

下一次获取的时候可以:

const request = new Request('/samples/service-worker/basic/', { method: 'GET' })
const cache = await caches.open('hello-cache-v1');
const matchResponse = await cache.match(request) // 此处可以获取上次存储的 Response

// 如果是带上路由 query 参数的形式
const request2 = new Request('/samples/service-worker/basic/?a=1', { method: 'GET' })
const matchResponse = await cache.match(request2, { 
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值