当前位置: 首页 > news >正文

企业H5站点升级PWA (四)

如何在 Service Worker 中实现版本控制和更新策略?

在你当前这个 sw.js 基础上,加“版本控制 + 更新策略”主要就是两块:

  1. 用版本号管理缓存(你已经有雏形)。
  2. 决定新版本什么时候生效(立即生效 / 下次刷新 / 用户确认)。

下面用尽量少的改动,把这两件事做完整。


1. 缓存版本控制:命名 + 清理

你现在:

const CACHE_NAME = 'densenapp-static-v1';

这是第一层版本控制。建议:

  • 把版本号单独提取出来,方便后续统一管理;
  • activate 里按前缀清旧版本。
const CACHE_VERSION = 'v1.0.0';
const CACHE_PREFIX = 'densenapp-static-';
const CACHE_NAME = `${CACHE_PREFIX}${CACHE_VERSION}`;

同时改 activate 里的清理逻辑(只删同前缀的旧版本):

self.addEventListener('activate', (event) => {event.waitUntil(caches.keys().then((keys) => {return Promise.all(keys.filter((key) => key.startsWith(CACHE_PREFIX) && key !== CACHE_NAME).map((key) => caches.delete(key)));}));self.clients.claim();
});

后续发新版,只要改 CACHE_VERSION,就会:

  • 安装:创建新缓存 densenapp-static-vX.Y.Z 并预缓存列表;
  • 激活:自动删除旧版缓存。

2. 更新策略:新 SW 什么时候接管页面

常见几种:

  1. 立即生效(当前打开的页面也强制切新 SW)
    适合你这种门店工具类应用:更新小、希望所有终端立刻一致。

  2. 下次打开才生效(默认行为)
    浏览器会在“所有旧 SW 控制的页面关闭”后再启用新 SW。

  3. 用户确认后再切换
    比较适合公众站点,这里就不展开了。

你现在在 install 里已经:

self.skipWaiting();

这一步是“让新 SW 直接进入 waiting -> activate”,配合 clients.claim(),基本就是立即接管策略。为了更可控,可以再加一个向页面广播“有新版本”的钩子。


3. 广播更新信息到页面(可选但推荐)

activate 里激活新版本后,给所有客户端发一条消息:

self.addEventListener('activate', (event) => {event.waitUntil((async () => {const keys = await caches.keys();await Promise.all(keys.filter((key) => key.startsWith(CACHE_PREFIX) && key !== CACHE_NAME).map((key) => caches.delete(key)));// 通知所有客户端:SW 已激活新版本const clientsList = await self.clients.matchAll({ type: 'window' });for (const client of clientsList) {client.postMessage({type: 'SW_ACTIVATED',version: CACHE_VERSION});}await self.clients.claim();})());
});

然后在你页面里(例如 index.js 末尾)监听这条消息,可以选择:

  • 直接 location.reload() 强刷;
  • 或展示 toast,让用户点“立即更新”。

一个简单的“自动刷新”示例:

if ('serviceWorker' in navigator) {navigator.serviceWorker.addEventListener('message', (event) => {if (event.data?.type === 'SW_ACTIVATED') {console.log('Service Worker 已更新到版本:', event.data.version);// 简单粗暴:直接刷新,让新静态资源生效window.location.reload();}});
}

这样,你的更新策略就是:

  • 发布新前端版本 → 改 CACHE_VERSION → 部署;
  • 客户端下次访问:
    • 下载新 sw.js
    • 预缓存新版静态文件;
    • 删除旧缓存;
    • 给页面发 SW_ACTIVATED
    • 页面收到后自动刷新,所有终端立刻跑在新版本资源上。

4. PRECACHE_URLS 的版本化

如果你以后想做更细粒度的缓存更新,可以给每个静态资源附上“指纹”(hash)或查询参数:

const PRECACHE_URLS = ['./index.html?v=1.0.0','./index.js?v=1.0.0','./index.css?v=1.0.0',// ...
];

只要构建时版本号或 hash 变了,浏览器就会认为是一个“新 URL”,从而强制重新拉取并缓存。

在你当前手工维护的环境里,最简单的做法是:

  • 每次发版同时:
    • CACHE_VERSION;
    • PRECACHE_URLS 里的 ?v=... 一致的版本号。

不做也行,靠 CACHE_VERSION 变化 + 重新 addAll 一般已经足够,主要看是否有中间层缓存(CDN)等。


5. 小结:在你现有 sw.js 上需要改的点

  1. 顶部增加版本常量,调整 CACHE_NAME
const CACHE_VERSION = 'v1.0.0';
const CACHE_PREFIX = 'densenapp-static-';
const CACHE_NAME = `${CACHE_PREFIX}${CACHE_VERSION}`;
  1. activate 里按前缀清旧版本 + 可选广播:
self.addEventListener('activate', (event) => {event.waitUntil((async () => {const keys = await caches.keys();await Promise.all(keys.filter((key) => key.startsWith(CACHE_PREFIX) && key !== CACHE_NAME).map((key) => caches.delete(key)));const clientsList = await self.clients.matchAll({ type: 'window' });for (const client of clientsList) {client.postMessage({type: 'SW_ACTIVATED',version: CACHE_VERSION});}await self.clients.claim();})());
});
  1. 页面侧(index.js)监听 message,决定是否自动刷新:
if ('serviceWorker' in navigator) {navigator.serviceWorker.addEventListener('message', (event) => {if (event.data?.type === 'SW_ACTIVATED') {console.log('SW 已更新到版本:', event.data.version);window.location.reload();}});
}

如果你希望更新“不要打断正在操作的用户”,可以把 window.location.reload() 换成“弹一个自定义对话框:检测到新版本,是否立即刷新?”,逻辑类似,只是延迟刷新时机。

http://www.jsqmd.com/news/392392/

相关文章:

  • 题解:洛谷 P3916 图的遍历
  • 【硬盘】个人数据备份的各种方式##37
  • 题解:洛谷 P5318 【深基18.例3】查找文献
  • 题解:洛谷 P4017 最大食物链计数
  • 题解:洛谷 P1113 杂务
  • 别只会用 getData!Watcher 注册源码流程全拆解
  • Java线程解析:5种线程创建方法及应用场景 - 指南
  • 题解:洛谷 P2814 家谱
  • 题解:洛谷 P3879 [TJOI2010] 阅读理解
  • 2024 年 09 月 二级真题(1)--数位之和
  • 2026年龙岩连城长汀红白喜事鼓吹铜管乐队演出推荐:客家非遗与市场化服务的平衡之选 - 小白条111
  • 题解:洛谷 P4305 [JLOI2011] 不重复数字
  • 12:内核ROP与提权技术
  • 13:现代内核保护机制与绕过技术
  • 14:跨架构内核漏洞利用差异
  • 超市在线销售与分析|基于Python + Django超市在线销售与分析系统(源码+数据库+文档)
  • AI知识图谱构建:企业智能搜索的底层架构
  • 大数据领域数据中台的教育培训机构数据分析
  • 一天一个开源项目(第26篇):ZeroClaw - 零开销、全 Rust 的自主 AI 助手基础设施,与 OpenClaw 的关系与对比
  • OpenClaw(Clawdbot)部署指南:2026年天翼云部署快速上手
  • 彼得林奇的“家庭作业“投资法
  • 实用指南:Elasticsearch:监控 LLM 推理和 Agent Builder 使用 OpenRouter
  • AI提示系统反馈机制设计:如何解决“反馈噪音”问题?
  • 企业H5站点升级PWA (一)
  • 456348568
  • 75757
  • MongoDB备份策略:大数据场景下全量+增量备份的实现与恢复测试
  • AI训练算力利用率低?架构师的4个算力优化+调度方案
  • OpenClaw(Clawdbot):2026阿里云部署教程,掌握技巧超容易
  • 企业H5站点升级PWA (三)