本文目录导读:
- 场景一:浏览器端静态资源缓存(前端最常指)
- 场景二:服务端 OpCache(PHP 运行环境常见)
- 场景三:构建工具持久化缓存(Webpack/Vite/Vite Node.js/Java 编译缓存)
- 总结:5 条防坑铁律
源码缓存”的使用,这个术语在不同技术栈中含义差异较大,通常可能指 浏览器静态资源缓存、Webpack/Vite 等构建工具的持久化缓存,或是 服务端代码的 OpCache(操作码缓存)。
为了给你最精准的答案,我将覆盖最常见的三种场景,列举其中开发者最容易踩的坑:
浏览器端静态资源缓存(前端最常指)
这是指 HTML、CSS、JS、图片等文件的缓存策略。易错点主要围绕“更新后用户看到的还是旧版本”。
文件名 Hash 没变(强缓存坑)
- 错误表现:修改了
app.js代码,重新构建后文件名仍是app.js,浏览器直接读取本地缓存(200 from disk cache),导致新功能不生效。 - 正确做法:使用 内容哈希(Content Hash),如
app.a1b2c3.js,只有当文件内容变化时,哈希值才变,浏览器才会请求新文件。 - 注意点:如果你的 HTML 文件也被强缓存了,即便 JS 名字变了,用户拿到的 HTML 仍是旧的,脚本依然加载旧版本。HTML 通常应设为
no-cache(协商缓存)。
设置 Cache-Control: immutable 后无法强制刷新
- 错误表现:为了极致缓存,设置了
Cache-Control: max-age=31536000, immutable,这告诉浏览器在这个文件过期前,完全跳过服务端验证,连 F5 刷新都无效。 - 正确做法:除非配合文件名 Hash,否则不要轻易使用
immutable,普通开发调试时,建议用no-cache或短时间max-age。
代理/CDN 缓存与源站不一致(中间人缓存坑)
- 错误表现:源站已经更新了
main.js,但 CDN 边缘节点还有旧的缓存,导致部分地区用户访问异常。 - 正确做法:在响应头中同时设置
Cache-Control: public, max-age=0, s-maxage=86400。s-maxage专门控制 CDN 缓存时间,可以比客户端缓存更短,并配合 CDN 的强制刷新 API 使用。
服务端 OpCache(PHP 运行环境常见)
这是指 PHP(如 OpCache、APCu)或 Python(如 .pyc 文件缓存)的字节码缓存。
修改了源文件但 OpCache 未过期
- 错误表现:你用 FTP 上传了新的
index.php,但页面始终显示旧内容,甚至报错。 - 原因:PHP 的 OpCache 默认
validate_timestamps=0(生产环境推荐),不检查文件更新时间,直接读取内存中的旧字节码。 - 正确做法:
- 环境变量法:设置
opcache.revalidate_freq=2和opcache.validate_timestamps=1(开发环境)。 - 手动清除法:生产环境部署后,通过
opcache_reset()函数重启缓存,或使用php -r 'opcache_reset();'命令。 - 文件名轮转法:类似前端,PHP 框架重启(如 Laravel 的
php artisan optimize:clear)。
- 环境变量法:设置
共享内存耗尽导致缓存被逐出
- 错误表现:服务器刚重启时很快,跑了一段时间后变慢。
- 原因:
opcache.memory_consumption设置得太小(默认 128MB),当代码占用超过限制,旧的缓存会被覆盖,产生大量缓存未命中(Cache Miss)。 - 正确做法:监控
opcache_get_status()中的memory_usage,确保free_memory不低于 20%,通常大型项目需要设置为 512MB 或更高。
构建工具持久化缓存(Webpack/Vite/Vite Node.js/Java 编译缓存)
这是指增量编译时的磁盘缓存文件夹(如 node_modules/.cache、.tsbuildcache 等)。
缓存污染导致编译报错
- 错误表现:你切换了分支、升级了依赖,或者换了个 Node 版本(如从 18 到 22),构建直接报奇怪错误。
- 原因:旧的缓存文件是基于旧依赖或旧 Node ABI 生成的,与当前环境不兼容。
- 正确做法:在
CI/CD构建或切换分支时,删除缓存目录(rm -rf node_modules/.cache),可以使用 Webpack 的version字段自动失效。
缓存与源码路径强关联(Monorepo 坑)
- 错误表现:在 Monorepo 中,多个子项目共享同一个构建缓存目录,A 项目构建后,B 项目构建直接读取 A 的缓存,导致模块路径或状态异常。
- 正确做法:为每个子项目设置独立的
cache目录,或者在缓存 Key 中包含项目路径、环境变量等标识。
5 条防坑铁律
- 前端:强缓存只加给带 Hash 的文件,HTML 永远用
no-cache。 - 后端 OpCache:部署脚本必须包含
opcache_reset()或重启 PHP-FPM。 - 构建工具:换分支、升级环境、报错时,优先删除
.cache文件夹试试。 - 测试:多人协作或 CI/CD 环境下,测试时务必检查“无痕模式”或强制刷新(Ctrl+F5)。
- 监控:生产环境,给 OpCache 或构建缓存加个监控告警,防止内存溢出或异常清空。
如果你指的是其他特定技术(如 Java 的 ClassLoader 缓存、iOS 的 NSCache、图片缓存库等),请补充说明,我可以为你进一步细化。
标签: 易错点