You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

处理Service Worker更新时,是否真的需要所有这些多重检查?

Service Worker 更新检查的触发场景与必要性分析

问题背景

我跟着Jake Archibald在Udacity的《离线Web应用》教程学习Service Worker,对教程里更新练习的解决方案框架有疑问。这个方案包含三个检查,对应三种更新状态,但我测试后只触发了第三个(reg.waiting)。

我的测试步骤:

  • 在localhost:8080首次加载页面,完成Service Worker的注册、安装和激活
  • 修改Service Worker(比如在缓存文件数组中添加/tmp.txt)
  • 刷新页面

首次刷新没触发任何检查,第二次刷新触发了reg.waiting检查。我懂Service Worker生命周期,但不清楚另外两个检查(updatefound事件监听、installingSw检查)的触发场景,想确认这三个检查是否都有必要?

教程提供的代码:

(async() => {
  if ("serviceWorker" in navigator) {
    try {
      const reg = await navigator.serviceWorker.register("/sw.js");

      if (!reg || !navigator.serviceWorker.controller) {
        return;
      }
      // Possible states of new updates:
      // - 1. There are no updates yet, a new update may arrive
      // - 2. An update is in progress
      // - 3. A waiting update exists (already installed)
      // 1.
      addEventListener("updatefound", () => {
        console.log("updatefound");
        const sw = reg.installing;
        trackInstallation(sw);
      });
      // 2
      const installingSw = reg.installing;
      if (installingSw) {
        console.log("installingSw");
        trackInstallation(installingSw);
        return;
      }
      // 3
      if (reg.waiting) {
        console.log("reg.waiting");
        const sw = reg.waiting;
        notifyUpdate();
        return;
      }
      console.log("nothing");
    } catch (error) {
      console.error("Service worker registration failed.", error);
    }
  }
})();

function trackInstallation(worker) {
  worker.addEventListener("statechange", () => {
    if (worker.state === "installed") {
      notifyUpdate();
    }
  });
}

function notifyUpdate() {
  alert("There's a new update!");
}

三个检查的触发场景解析

1. updatefound 事件监听(“暂无更新但可能到来”)

这个事件在浏览器检测到新的Service Worker文件(与当前激活SW的哈希值不一致),开始下载并进入安装阶段时触发。

你的测试流程里,第一次修改SW后刷新页面,浏览器会在后台异步执行更新检查、下载新SW并启动安装——但页面注册SW的代码执行时,updatefound事件还没触发,所以看不到日志。等安装完成后,新SW进入waiting状态,第二次刷新页面时,代码直接检测到reg.waiting就触发了提示。

如果想触发这个事件的日志,可以在修改SW后,先打开DevTools的Application面板手动点击“更新”,或者在页面注册SW后等待几秒,让异步的更新检查完成,就能看到updatefound的打印。

2. reg.installing 检查(“更新进行中”)

这个检查是为了捕获页面加载时,已经有一个SW处于安装阶段的场景,比如:

  • 用户打开页面时,之前的某个标签页已经触发了SW更新,且安装还在进行中
  • 浏览器后台自动更新SW(比如设置了定期检查),刚好在页面加载时处于安装状态

你的测试流程里,每次修改后立刻刷新,安装过程很快完成,页面加载时reg.installing已经不存在了,所以不会触发这个分支。

3. reg.waiting 检查(“已有等待安装的更新”)

这就是你测试到的场景:新SW已经完成安装,但因为当前页面还在使用旧的激活SW,新SW会进入waiting状态,等待所有被旧SW控制的页面关闭后才能激活。第二次刷新页面时,代码检测到这个等待的SW,触发更新提示。

三个检查是否必要?

是的,三个检查覆盖了所有可能的更新状态,缺一不可:

  • updatefound:监听未来可能发生的更新,确保新SW开始安装时能跟踪进度,安装完成后及时提示用户
  • reg.installing:处理页面加载时已经在进行的安装,避免错过正在进行的更新
  • reg.waiting:处理已经完成安装、等待激活的更新,让用户及时知道有可用更新

如果缺少任何一个,都会导致某些更新场景下无法给用户正确的提示。

内容的提问来源于stack exchange,提问作者aderchox

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 09:46:40