feat: 添加 Service Worker 缓存与更新流程

- 为同源资源添加网络优先策略,并在离线时回退到缓存
- 缓存带版本号的 CDN 资源,并在发布更新时保留独立缓存条目
- 改进版本更新检查,避免清除 localStorage 或无关缓存
- 将 Service Worker 纳入部署流程并更新相关文档
This commit is contained in:
eddy
2026-07-20 02:22:15 +08:00
parent a878899512
commit 738275b493
6 changed files with 226 additions and 16 deletions
+25 -1
View File
@@ -15,7 +15,7 @@
integrity="sha384-t1nt8BQoYMLFN5p42tRAtuAAFQaCQODekUVeKKZrEnEyp4H2R0RHFz0KWpmj7i8g"
crossorigin="anonymous" referrerpolicy="no-referrer">
<script>
const ASSET_VERSION = '20260719-4';
const ASSET_VERSION = '20260720-1';
window.APP_VERSION = ASSET_VERSION;
const stylesheets = [
'styles/variables.css',
@@ -105,5 +105,29 @@
<script>
document.write(`<script type="module" src="js/main.js?v=${ASSET_VERSION}"><\/script>`);
</script>
<script>
// 注册 Service Worker:由它统一保证模块图不陈旧并提供离线回退。
// 注册失败(如旧版 iOS 不支持)不影响使用,上方 ?v= 版本号仍作兜底。
if ('serviceWorker' in navigator) {
const needsFirstControlledReload = !navigator.serviceWorker.controller;
let reloadingForServiceWorker = false;
if (needsFirstControlledReload) {
// 首次取得页面控制权后刷新一次,让首轮已加载的子资源也经过 SW 并写入离线缓存。
navigator.serviceWorker.addEventListener('controllerchange', () => {
if (reloadingForServiceWorker) return;
reloadingForServiceWorker = true;
window.location.reload();
});
}
window.addEventListener('load', () => {
// updateViaCache: 'none' 让 sw.js 本身始终走网络校验,避免被 HTTP 缓存拖住策略更新。
navigator.serviceWorker.register('sw.js', { updateViaCache: 'none' }).catch(error => {
console.warn('Service Worker 注册失败,应用仍可正常使用:', error);
});
});
}
</script>
</body>
</html>