HTTP缓存详解:ETag、Cache-Control与CDN

Web2026-09-28TryQuickToolBox

为什么你的网站感觉慢(以及缓存如何解决)

你已经优化了图片、压缩了CSS,甚至升级了服务器。然而,回访用户仍然体验到缓慢的加载时间,你的源服务器也在消耗带宽。罪魁祸首是什么?低效的HTTP缓存。如果没有正确的缓存头部,浏览器会在每次访问时重新下载相同的资源,CDN也无法有效工作。

HTTP缓存是最高杠杆的性能优化之一。它减少延迟、降低带宽成本,并减轻源服务器的负载。在本指南中,我们将分解关键机制:ETag、Cache-Control以及CDN如何融入其中。你将学到正确实现它们的实用策略。

HTTP缓存的工作原理:全局视角

当浏览器请求资源时,它可以从源服务器获取,也可以提供本地存储的副本。HTTP缓存定义了存储副本何时被视为新鲜以及何时必须重新验证的规则。

存在两种主要的缓存类型:

两者都依赖HTTP头部来决定新鲜度和重新验证。最重要的两个头部是Cache-Control和ETag。

Cache-Control:新鲜度规则

Cache-Control是定义缓存策略的主要头部。它是一个基于指令的头部,告诉缓存如何处理响应。

关键指令

示例:Cache-Control: public, max-age=31536000, immutable对于带有哈希文件名的静态资源是理想的。

ETag与条件请求

ETag(实体标签)是资源特定版本的标识符。当资源更改时,ETag会更改。浏览器使用ETag进行条件请求:它们在If-None-Match头部中发送存储的ETag。如果资源未更改,服务器会响应304 Not Modified且没有正文,从而节省带宽。

类似地,Last-Modified与If-Modified-Since一起工作,但ETag更精确(它们可以检测同一秒内的更改)。

如何生成ETag

大多数Web服务器和框架会自动生成ETag。例如,在Express.js中,你可以通过app.set('etag', 'strong')启用它。在Nginx中,静态文件默认开启ETag。

强ETag(例如"abc123")保证字节级一致性。弱ETag(例如W/"abc123")表示语义等价,而非精确字节。

CDN缓存:大规模共享缓存

CDN(内容分发网络)充当全球分布的共享缓存。它们在边缘位置缓存你的内容,从附近的接入点为用户提供服务。这减少了延迟并卸载了源服务器。

CDN尊重Cache-Control头部,但通常有自己的配置。关键概念:

使用CDN时,设置带有s-maxage的Cache-Control,以单独控制共享缓存的新鲜度。例如:Cache-Control: public, max-age=600, s-maxage=3600表示浏览器缓存10分钟,但CDN缓存1小时。

缓存头部比较

头部 用途 示例
Cache-Control 定义新鲜度和缓存规则 public, max-age=3600
ETag 资源版本的唯一标识符 "abc123"
Last-Modified 最后修改的时间戳 Wed, 21 Oct 2025 07:28:00 GMT
Expires 遗留的绝对过期日期 Wed, 21 Oct 2025 07:28:00 GMT
Vary 指定影响缓存的头部 Accept-Encoding

注意:Expires已被Cache-Control取代,但旧客户端仍在使用。

Web应用的实用缓存策略

遵循以下步骤实现有效的缓存:

  1. 为静态资源添加指纹:使用哈希文件名(例如app.a1b2c3.js),并设置较长的max-age和immutable。当文件更改时,哈希更改,从而破坏缓存。
  2. 为HTML设置适当的Cache-Control:HTML通常应为no-cache或较短的max-age,以便用户快速获得更新。使用ETag进行重新验证。
  3. 使用Vary: Accept-Encoding:如果你提供压缩和未压缩版本,这确保缓存分别存储它们。
  4. 利用CDN的s-maxage:为共享缓存设置较长的s-maxage以减少源服务器负载,同时根据需要保持浏览器缓存较短。
  5. 明智地失效:在部署关键更新时使用CDN清除API。对于静态资源,指纹化避免了清除的需要。
  6. 监控缓存命中率:使用CDN分析确保缓存有效。低命中率意味着头部配置错误。

常见陷阱及如何避免

测试你的缓存设置

使用浏览器DevTools(网络选项卡)检查响应头部,查看资源是否从缓存提供(查找“(from disk cache)”或“(from memory cache)”)。对于CDN行为,使用curl -I检查如X-Cache或CF-Cache-Status的头部。像WebPageTest这样的工具可以可视化多次访问的缓存情况。

常见问题

ETag和Last-Modified有什么区别?

ETag是一个不透明标识符,当资源更改时会改变,而Last-Modified是一个时间戳。ETag更精确,因为它们可以检测同一秒内的更改,并且不依赖时钟同步。

何时应使用no-cache vs no-store?

当你希望缓存存储响应但在每次使用前与源服务器重新验证时,使用no-cache。对于绝不能由任何缓存写入磁盘或内存的敏感数据,使用no-store。

CDN如何处理缓存失效?

CDN提供清除API,允许你从边缘缓存中删除特定URL或整个目录。有些还支持软清除,将内容标记为过时并在下次请求时重新验证。为资源添加指纹通常比清除更高效。

结论

掌握ETag、Cache-Control和CDN的HTTP缓存对于构建快速、可扩展的Web应用至关重要。从为静态资源和HTML设置正确的头部开始,利用带有s-maxage的CDN共享缓存,并始终测试你的配置。缓存头部的微小变化可以带来显著的性能提升。

需要快速分析服务器日志以查看缓存命中率?尝试我们的Nginx日志分析器来解析和可视化你的访问日志。