service-worker
Service Worker 缓存
Service Worker 是一种独立于浏览器主线程的工作线程,与当前的浏览器主线程是完全隔离的,并有自己独立的执行上下文(context)。
由于 Service Worker 线程是独立于主线程的工作线程,所以在 Service Worker 中的任何操作都不会影响到主线程。
PWA(Progressive Web Apps)应用多项技术
来改善用户体验的 Web App,为 Web App 提供类似 Native App 的用户体验。
其核心技术包括 Web App Manifest,Web Push,Service Worker 和 Cache Api 等,用户体验才是 PWA 的核心。 PWA 主要特点如下:
- 可靠 - 即使在网络不稳定甚至断网的环境下,也能瞬间加载并展现
- 用户体验 - 快速响应,具有平滑的过渡动画及用户操作的反馈
- 用户黏性 - 和 Native App 一样,可以被添加到桌面,能接受离线通知,具有沉浸式的用户体验
浏览器在请求资源时会遵循以下缓存顺序-优先Service Worker缓存
Service Worker缓存:Service Worker 检查资源是否在其缓存中,并根据其编程的缓存策略决定是否返回资源本身。请注意,需要在 Service Worker 中创建一个 fetch 事件处理程序并拦截网络请求,这样才能从 Service Worker 的缓存。
HTTP 缓存(也称为浏览器缓存):如果资源位于 HTTP 缓存中且尚未过期,则浏览器会自动使用 HTTP 缓存中的资源。
如果在 Service Worker 缓存或 HTTP 缓存中未找到任何内容,则浏览器将向网络请求资源。如果资源未在 CDN 中缓存,则请求必须返回到源服务器。
资源的更新
当有任何的资源(HTML、JS、Image、甚至是 sw.js 本身)需要更新时,都需要改变 sw.js。因为有了 sw.js,整个应用的入口变成了 sw.js,而非原先的 HTML。每当用户访问页面时,不管你当前是不是命中了缓存,浏览器都会请求 sw.js,然后将新旧 sw.js 进行字节对比,如果不一样,说明需要更新。因此,你能看到在 Demo 中,我们有一个 VERSION 字段,它不仅代表 sw.js 本身的版本,更代表整个应用的版本。
每次 sw.js 的更新,都会根据 VERSION 字段新建一个缓存空间,然后把新的资源缓存在里面。等到旧的 sw.js 所控制的网页全部关闭之后,新的 sw.js 会被激活,然后 在 activate 事件中删除旧缓存空间。这样既能保证在同时打开多个网页时更新 sw.js 不出差错,也能及时删除冗余的缓存。
Service Worker 缓存策略以及每种策略的适用场合
策略 新鲜度理论 用例
仅网络 内容必须始终保持最新。 付款和结帐 余额表
网络回退到缓存 最好提供新内容。但是,如果网络出现故障或不稳定,也可以提供稍旧的内容。 及时数据/价格和费率(需要免责声明)/订单状态
重新验证时过期 (Stale-while-revalidate) 可以立即提供缓存内容,但将来应该使用更新的缓存内容。 新闻提要/产品列表页面/留言
缓存优先,回退到网络 内容不重要,并且可以从缓存中获得以提高性能,但 Service Worker 应该偶尔检查是否有更新。 应用外壳/公共资源
仅缓存 内容很少改变。 静态内容
除了对缓存逻辑的精细控制外,Service Worker缓存还具有以下优势
- 为源提供更多内存和存储空间:浏览器基于每个源分配 HTTP 缓存资源。
换句话说,如果您有多个子域,它们将共享相同的 HTTP 缓存。无法保证您的源/域的内容会长时间保留在 HTTP 缓存中。例如,用户可以通过以下方式清除缓存:在浏览器的设置 UI 中进行手动清理或者触发页面上的硬重新加载。使用 Service Worker 缓存,您的缓存内容保持缓存状态的可能性要高得多。请参阅持久存储以了解更多信息。
- 网络不稳定或离线时提高灵活性:使用 HTTP 缓存,您只能做二元选择:要么缓存资源,要么不缓存。使用 Service Worker 缓存,您可以更轻松地缓解小“小问题”(使用“重新验证时过期”策略)、提供完整的离线体验(使用“仅缓存”策略),或者是介于二者之间,例如,对于自定义 UI,必要时,页面的一部分来自 Service Worker 缓存,而某些部分被排除在外(使用“设置捕获处理程序“策略)。
如果网络不稳定,Service Worker 缓存仍可返回缓存的资源。另一方面,当网络不稳定或中断时,HTTP 缓存将变得不可靠。
初次访问不会触发 fetch 事件
只有再次访问页面才会触发 fetch 事件。如果你的页面加载时没有 Service Worker,那么它所依赖的其他资源请求也不会触发 fetch 事件。