当你的网站图片、CSS 和 JavaScript 文件每次访问都重新下载时,页面加载速度会明显变慢,服务器压力也随之增加。这正是浏览器缓存策略需要解决的问题。很多站长以为开启缓存就万事大吉,但配置不当反而会导致资源过期或回源频繁。本文将从实际问题切入,带你逐步配置一套合理的缓存策略。
为什么浏览器缓存策略会失效?
常见的现象是:修改了 CSS 文件,但用户浏览器仍然加载旧版本;或者明明设置了缓存,但每次请求都回源。这通常是因为没有明确指定资源的缓存时间,或者使用了错误的响应头。浏览器缓存的核心在于 Cache-Control 响应头,它决定了资源是否可缓存、缓存多久以及如何验证。
第一步:明确哪些资源需要缓存
并非所有资源都适合长时间缓存。静态资源(如图片、CSS、JS、字体)通常可以缓存较长时间,而 HTML 页面、API 响应等动态内容则可能需要短缓存或禁用缓存。你可以根据资源的更新频率和重要性来划分:
- 图片、字体等不经常变动的资源:设置较长的
max-age,例如 30 天或 1 年。 - CSS/JS 文件:如果使用版本号或文件名哈希,可以设置长期缓存;否则建议短缓存(如 1 小时)并配合协商缓存。
- HTML 页面:通常设置
no-cache,让浏览器每次验证,但可以配合ETag或Last-Modified减少传输量。
第二步:配置 Cache-Control 响应头
在服务器或 CDN 层设置 Cache-Control 头。例如,Nginx 中可这样配置:
location ~* .(css|js)$ {
expires 30d;
add_header Cache-Control "public, max-age=2592000";
}
但要注意,expires 和 Cache-Control 同时存在时,后者优先级更高。此外,public 表示任何缓存(包括 CDN)都可以缓存,private 则只允许浏览器缓存。对于需要登录的页面,应使用 private 或 no-store。
第三步:利用 CDN 实现边缘缓存
CDN 是浏览器缓存的延伸,它能在离用户更近的节点缓存内容,减少回源延迟。以 Cloudflare 为例,其缓存功能默认会缓存静态资源,并遵循源站的 Cache-Control 头。你可以通过 Cache Rules 自定义哪些资源应被缓存以及缓存多久,实现更精细的控制。例如,对 API 响应设置较短的缓存时间,对图片设置长期缓存。
当启用 Tiered Cache 时,内容会在多个层级缓存,进一步提高命中率并减少源站负载。Cloudflare 还提供持久化存储来增加缓存时间,并支持即时清除缓存文件,强制获取最新版本。
第四步:处理缓存更新与失效
缓存策略的一大难题是更新。当你修改了 CSS 或 JS 文件,如果文件名不变,浏览器可能继续使用旧缓存。解决办法是采用文件指纹(如 style.abc123.css),或者每次更新后主动清除 CDN 缓存。Cloudflare 支持通过 API 或控制台单独清除某个文件的缓存,也可以全部清除。
对于 HTML 页面,使用 no-cache 并配合 ETag 可以让浏览器每次请求时向服务器验证,若内容未变则返回 304,减少传输数据量。
常见误区与取舍
- 误区一:所有资源都设置长缓存。这会导致更新后用户无法立即看到新内容,需要配合版本管理。
- 误区二:禁用缓存以提高新鲜度。这会增加服务器负载和加载时间,得不偿失。
- 取舍:缓存时间越长,性能越好,但新鲜度越差;反之亦然。你需要根据业务需求平衡。
- 注意:对于动态内容(如用户个人资料),应使用
private或no-store,避免泄露数据。
结合 Workers 实现自定义缓存逻辑
如果你的缓存需求复杂,例如需要根据用户地理位置或请求头动态决定缓存策略,可以使用 Cloudflare Workers 在边缘执行自定义代码。Workers 允许你拦截请求和响应,修改缓存行为,甚至实现基于 KV 存储的个性化缓存。例如,你可以为不同设备类型返回不同的缓存版本。
总结
浏览器缓存策略配置并不复杂,但需要根据资源类型和更新频率精细调整。从 Cache-Control 头入手,结合 CDN 边缘缓存,并处理好缓存失效问题,就能显著提升网站性能。记住,没有一劳永逸的配置,定期审查和测试是必要的。
参考资料
延伸阅读
