缓存与 hash 策略
约 499 字大约 2 分钟
2026-02-11
性能优化里最容易被低估的一点是缓存。
缓存策略做对后,用户二次访问通常只需下载变更文件;做错则会出现“改一行代码,所有文件缓存失效”。
hash / chunkhash / contenthash 的区别
| 占位符 | 变化粒度 | 影响 | 推荐度 |
|---|---|---|---|
[hash] | 整个构建级别 | 任一文件变化会导致全体文件名变化 | 不推荐 |
[chunkhash] | Chunk 级别 | 同 chunk 变化会联动 | 可用 |
[contenthash] | 文件内容级别 | 仅内容变化才改名 | 强烈推荐 |
占位符差异
为什么生产优先 contenthash
它解决的是“无关改动导致缓存抖动”的问题。
例如:
- 你只改了
A.js。 - 如果用
[hash],B.js也会换名,缓存全失效。 - 如果用
[contenthash],B.js不变,浏览器继续命中缓存。
推荐配置(长期缓存基线)
下面这份配置通常作为生产默认模板:
module.exports = {
output: {
filename: 'js/[name].[contenthash:8].js',
chunkFilename: 'js/[name].[contenthash:8].chunk.js',
},
optimization: {
moduleIds: 'deterministic',
chunkIds: 'deterministic',
runtimeChunk: 'single',
splitChunks: {
chunks: 'all',
},
},
};这里的 runtimeChunk: 'single' 是关键,它能减少运行时代码变化对业务 chunk hash 的干扰。
CDN 与 publicPath
如果产物部署在 CDN,必须给出明确公共前缀:
module.exports = {
output: {
publicPath: 'https://cdn.example.com/assets/',
},
};引入第三方 CDN 库时,可配合 externals 避免重复打包:
module.exports = {
externals: {
react: 'React',
axios: 'axios',
},
};使用注意事项
建议
- 生产默认采用
contenthash。 - 使用 deterministic ids 稳定 module/chunk 编号。
- 验证真实部署环境下
publicPath是否正确。
常见错误
- 使用
[hash]导致全量缓存失效。 - 忽略 runtime 抖动,导致无关文件名变化。
- CDN 全局变量名与
externals映射不一致。
最佳实践
- 把“缓存命中率”纳入发布后观测指标。
- 每次升级构建策略都做“变更文件影响面”对比。
- 和后端/CDN 同步缓存失效策略,避免互相抵消。
