热更新需四要素严丝合缝:资源加哈希后缀并禁用index.html强缓存;加载失败时降级fallback;采用内容哈希差分更新与模块化拆包;版本标识用manifest哈希存indexedDB并校验。

热更新必须绕开浏览器缓存机制
HTML5 游戏发布后,用户本地可能长期缓存旧版 index.html 或 main.js,导致新资源根本加载不到。这不是代码逻辑问题,而是 HTTP 缓存策略失控。
- 关键动作:对所有可变资源(
game.js、config.json、assets/下文件)强制添加版本参数或哈希后缀,例如game.a1b2c3.js;index.html本身则禁用强缓存(Cache-Control: no-cache或max-age=0) - 不要只改
meta标签或靠location.reload(true),这些在现代浏览器中基本无效 - CDN 配置需同步调整:确保
.js和.json文件的缓存 TTL 设为 1 年,而index.html设为 0 秒或通过 ETag 校验
资源加载失败时要有降级 fallback 路径
热更新过程中,新资源可能因网络中断、CDN 同步延迟或路径配置错误而 404,此时若直接报错白屏,用户就卡死了。
- 所有动态
fetch()或XMLHttpRequest加载资源的地方,必须包裹try/catch并检查response.status,不能只依赖then() - 预设 fallback:比如加载
manifest-v2.json失败时,自动回退到本地缓存的manifest-v1.json,再从中加载旧资源 - 引擎层如 Phaser 或 LayaAir,需重写
Loader.load()方法,在onFileError回调里触发降级逻辑,而非抛出未捕获异常
热更新包体积与差分策略直接影响成功率
全量替换 JS 包在弱网下极易中断,尤其当包体超过 2MB;用户中断后再次进入,可能处于“半更新”状态——HTML 是新版,但部分资源还是旧版。
- 必须使用基于内容哈希的差分更新:比较服务端
manifest.json与本地记录的哈希值,仅下载变更文件(如仅scene2.js和audio/boss.mp3) - 避免把所有逻辑塞进单个
bundle.js:按场景/模块拆包(login.chunk.js、battle.chunk.js),让热更粒度可控 - 差分包上传前用
gzip或zstd压缩,并在前端解压(LZString 或 WebAssembly 解压库),实测可降低 60%+ 传输量
本地存储的版本标识必须防篡改且可追溯
很多团队用 localStorage.setItem('version', '1.2.0') 记录当前版本,但用户手动修改或跨设备同步会导致校验失效,甚至引发资源错配。
立即学习“前端免费学习笔记(深入)”;
- 版本标识不应是纯语义版本号,而应是资源清单的完整内容哈希(如
sha256(manifest.json)),存在indexedDB中并加时间戳字段 - 每次启动时校验:比对当前
manifest.json哈希与本地存储值,不一致则标记“需热更”,并记录lastCheckTime防止高频轮询 - 严禁在
localStorage存敏感逻辑开关(如isDebugMode),这类字段一旦被用户修改,可能绕过热更流程直接加载调试资源











