延长了生命周期的共享工作器源试用

发布时间:2025 年 7 月 31 日

从 Chrome 139 开始,参与延长生命周期的共享 worker 的新源试用。该试验新增了一个 extendedLifetime: true 选项,可让共享 worker 在最后一个文档卸载后继续运行。

延长使用寿命功能的应用场景

许多网站都希望在用户离开网页时执行一些操作。例如,写入存储空间或将数据发回服务器,以保存状态或记录分析数据。

Web 平台提供了一些 API 来处理一些简单的使用情形,但每个 API 都有其局限性:

  • 同步 JavaScript API(例如 localStorage 写入)在卸载当前网页之前会运行完毕。
  • fetch API 有许多选项,例如 keepalive 和最近新增的 fetchLater,可让发送的请求在文档卸载后的一小段时间内继续存在。

不过,这些仅涵盖同步工作,最终的 fetch 请求除外。它们不允许使用 IndexedDB压缩流Web Crypto 等异步 API 进行哈希处理或加密。许多 API(尤其是较新的 API)都是异步的,以避免阻塞主线程,因此无法在卸载时使用这些 API 是一种限制。

另一种方法是使用 Service Worker,它们存在于各个网页生命周期之外。不过,这是一种相当重量级的解决方案,对开发者的生命周期和管理要求更为复杂,更不用说对用户的额外进程和内存要求了。它也不符合 service worker 的主要使用情形(充当网络请求的代理)。仅为了在页面卸载时完成某些工作而使用完整的 Service Worker 似乎有点过头了。

建议的解决方案

SharedWorker API 是一种更轻便的 API,用于将工作从主线程分流。不过,它们目前不会在来源的生命周期(即相应来源的最后一个网页卸载时)结束后继续存在。Chrome 建议向 SharedWorker API 添加一个新选项,以允许共享 worker 在文档销毁后继续存活一小段时间。

HTML 标准已鼓励实现方案在文档卸载后短时间内保持共享工作器处于活动状态,以便在同源页面之间导航时不会拆除然后重新创建共享工作器。扩展生命周期提案只是通过建议即使在用户未导航到同源目的地时,用户代理也应将共享工作器保持活跃一段时间,从而扩展了此功能,以便完成异步工作。

该提案旨在允许共享工作器在最后一个文档卸载后继续存在,存在时间与服务器工作器允许保持空闲的时间相同,对于 Chrome 而言为 30 秒。请注意,对于共享工作器,这是卸载后的最长使用期限,而不是空闲时间。也就是说,30 秒的限制从卸载时开始计算,而不是从空闲时间开始计算。已开始但尚未在该时间段内完成的工作将被取消。

启用延长生命周期

通过注册生命周期延长的共享 worker源试用,可以在网站上为用户启用此功能。或者,开发者可以使用 chrome://flags/#enable-experimental-web-platform-features 标志在自己的浏览器中启用该功能。

示例代码

选择加入试用或启用功能标志后,请按以下方式启用延长使用期限:

const myWorker = new SharedWorker("worker.js", { extendedLifetime: true });

由于共享工作器也支持 Blob,因此无需单独的脚本即可启用此功能。例如,如需将数据写入 IndexedDb,请执行以下操作:

const sharedWorkerScript = `
  const transaction = db.transaction("analytics", "readwrite");
  const store = transaction.objectStore("analytics");
  const request = store.get("visitCount");
  request.onsuccess = (event) => {
    const newCount = (event.target.result || 0) + 1;
    store.put(newCount, "visitCount");
  };
`;

document.addEventListener("pagehide", () => {
  const blob = new Blob([sharedWorkerScript], { type: "text/javascript" });
  const blobURL = URL.createObjectURL(blob);
  new SharedWorker(blobURL, { extendedLifetime: true });
});

我们还提供了一个示例应用:https://sharedworker-extendedlifetime.netlify.app/。当网页重新加载(或在 30 秒内关闭并重新打开)时,之前的计算结果仍然可用。

您可以在 chrome://inspect/#workers 中查看网站的共享工作器,我们很快会增强此功能,以显示是否使用了 extendedLifetime 选项。扩展生命周期的共享 worker 在网页卸载后也会继续在此页面上显示 30 秒。

分享您的反馈

我们期待您就延长生命周期的共享 worker 源轨迹提供反馈。

我们正在 GitHub 上讨论 API 的形状,并提供了更详细的技术说明

如需针对 Chrome 的实现提供反馈,请提交 Chromium bug