# WebWorker

Web Worker:靓仔,要不要试试开个「子线程」耍耍?很快的哦! (opens new window)

你不知道的 Web Workers (上)[7.8K 字 | 多图预警] (opens new window)

# ServiceWorker

# 简介

如果您钻研 Javascript 或从事开发工作已经有一段时间了,那您一定听说过 Service Worker。它到底是什么?简单来说,它是浏览器在后台运行一个脚本,与 web 页面或 DOM 没有任何关系,并具有开箱即用的特性。 这些功能包括代理网络请求、推送通知以及后台同步。Service Worker 能保证用户拥有良好的离线体验。

您可以将 Service Worker 看作是一个位于客户端和服务器之间的人,对服务器的所有请求都将通过 Service Worker。本质上来说,它就是个中间人。由于所有请求都通过 Service Worker,所以它能够动态拦截这些请求。

不同的 Service Worker 运行在不同的线程上,它们是没有权限直接访问 DOM 元素的,就像一个个与 DOM 和 Web 页面没有交互的 Javascript。虽然不能直接访问 DOM,但是它们可以通过 postMessage 间接访问 DOM。如果您打算构建一个渐进式 Web 应用,那么您应该熟练掌握 Service Worker 和缓存策略。

注意: Service worker 不是 Web Worker。Web Worker 是在不同线程上运行运行负载密集型计算的脚本,它不会阻塞主事件循环,也不会阻塞 UI 的渲染。

# 缓存策略

  • 仅缓存(Cache only)

最简单的。就像它名字所说的,它意味着所有请求都将进入缓存。

何时使用:当您只想访问静态资源的时候使用它。

  • 仅网络(Network only)

客户端发出请求,Service Worker 拦截该请求并将请求发送到网络。

何时使用:当不是请求静态资源时,比如 ping 检测、非 GET 的请求。

  • 缓存优先,若无缓存则回退到网络请求(Cache,falling back to network)

这是之前在 fetch 事件中讨论的内容,如果请求缓存不成功,Service Worker 则会将请求网络。

何时使用:当您在构建离线优先的应用时

  • 网络优先,若获取失败则回退到缓存获取(Network falling back to cache)

首先,Service Worker 将向网络发出一个请求,如果请求成功,那么就将资源存入缓存。

何时使用:当您在构建一些需要频繁改变的内容时,比如实时发布的页面或者游戏排行榜。当您最新数据优先时,此策略便是首选。

  • 缓存资源与网络资源,谁快用谁

  • 先使用缓存,再访问网络更新缓存 (Fastest)

  • 常规回退(Generic fallback) 当两个请求都失败时(一个请求失败于缓存,另一个失败于网络),您将显示一个通用的回退,以便您的用户不会感受到白屏或某些奇怪的错误。

  • 检查缓存离线时间

不同缓存的时效时间可以由服务获取,然后开启定期检查,消灭失效资源。

setInterval(async () => {
  const res = await fetch('/pageA/sw-cache-config');
  const data = await res.json();
  caches.checkCacheLifeTime(data);
}, SW_CACHE_INTERVAL);
1
2
3
4
5

HTML: 可以离线访问使用 NetworkFirst,不需要离线访问,使用 NetworkOnly JS & CSS: 情况比较复杂,因为一般站点的 CSS,JS 都在 CDN 上,SW 并没有办法判断从 CDN 上请求下来的资源是否正确(HTTP 200),如果缓存了失败的结果,问题就大了。这种我建议使用 Fastest 策略,既保证了页面速度,即便失败,用户刷新一下就更新了。 图片:可以使用 CacheFirst,并设置缓存失效时间。

使用 ServiceWorker 缓存来优化体验 (opens new window)

[译] 理解 Service Worker 和缓存策略 (opens new window)