解决 PWA 检测更新策略的 bug

阅读时长 3 分钟读完

最近,我们在开发 Progressive Web App(PWA)时遇到了一个问题:即使我们在 Service Worker 中实现了检测并提示用户更新的逻辑,但一些用户仍然没有成功更新到最新版本。经过调查,发现这是因为缓存机制的原因造成的。

问题原因

在我们的 PWA 中,有一个服务端接口会返回一个版本号,用于比较当前用户使用的版本是否是最新版。我们会在 Service Worker 中监听 fetch 事件,并在其中调用该接口获取版本号,然后与本地存储的版本号进行比较。如果不一致,我们会主动触发更新操作。

然而,我们发现有些用户在获取版本号后,并没有触发 Service Worker 的更新。经过排查,我们发现这是因为浏览器在获取资源时会优先读取缓存,而并没有直接去请求服务器,从而导致版本号的比对不正确,也就无法触发 Service Worker 的更新了。

解决方案

为了解决上述的问题,我们可以在 Service Worker 中通过修改请求的方式来实现强制刷新的效果。

在 Service Worker 中的 fetch 监听函数中,我们可以获取到发出请求的 Request 对象和对应的 Response 对象。我们可以将 Request 对象克隆一份,并在克隆的 Request 对象中加上一个特殊的请求头,比如 Cache-Control: no-cache。这样一来,浏览器在获取资源时会优先请求服务器,而不是从缓存中读取,从而避免了上述的问题。

下面是具体的实现代码示例:

-- -------------------- ---- -------
------------------------------ ----- -- -
  ----------------------- -------- -- -
    ----- ------- - ----------------------
    ----- -------- - ----- -------------- - ------ ---------- ---
    ----- --------------- - -----------------
    -- ----
    ------------------------------------ ------------------
    -- ------
    ------ ---------
  -----
---

----- -------- -------------------- --------- -
  -- ---------------
-

在上述代码中,我们通过调用 fetch 方法时传入 { cache: 'no-store' } 的参数,告诉浏览器不要读取缓存。这样一来,就可以避免在获取版本号等关键性信息时出现的问题。

总结

在开发 PWA 时,需要特别注意缓存机制在更新策略中的影响。通过在 Service Worker 中修改 Request 对象,我们可以避免浏览器优先读取缓存的问题,从而保证更新策略的准确性。同时,这也为我们在设计其它 PWA 的检测更新逻辑时提供了一些思考方向。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64e475daf6b2d6eab3fe70a7

纠错
反馈