深浅主题
静态资源缓存导致版本不一致
问题现象
发布后白屏、Failed to fetch dynamically imported module,或旧页面加载新接口产生字段错误;无痕窗口表现正常。
适用环境
Vite 构建、反向代理/CDN、浏览器缓存;可能包含 Service Worker。
本文是可复用的排障示例,不代表某次个人生产事故。命令中的名称、账号和数据均为示例,执行前请替换为已确认的目标。
复现或诊断步骤
- 保存失败资源 URL、状态码、Content-Type、Cache-Control、Age 和 ETag。
- 对比 HTML 中引用的资源哈希与部署目录实际文件。
- 暂时禁用浏览器缓存,并检查 Service Worker 与 CDN 是否另有缓存层;不要直接清空所有用户数据作为结论。
原因分析
旧 HTML 引用了已经删除的哈希资源,或部署逐个覆盖使 HTML 与 JS 短暂不一致。HTML 长时间 immutable 会延长版本错配;Service Worker 还可能独立持有旧缓存。
修复示例
caddyfile
:8080 {
root * /srv/site
@hashed path /assets/*
header @hashed Cache-Control "public, max-age=31536000, immutable"
header !@hashed Cache-Control "no-cache"
file_server
}只有带内容哈希且不会原地修改的资源使用长期缓存。HTML、搜索入口和版本元数据采用重新验证。用版本目录原子切换,且在过渡期保留旧哈希资源或明确处理旧页面重载;多实例发布要保证所有节点都能提供被引用文件。
验证方法
保持旧标签页打开后发布新版本,触发懒加载;再刷新新标签页。检查两个版本资源是否可用,并确认 404 资源不会被代理错误缓存。回滚时切回完整旧版本及其资产。
常见误区
修改文件名但保留长期缓存的 HTML 仍会失败。不能靠给所有 URL 加时间戳替代正确缓存策略;清理 CDN 前应确认源站已一致。