Skip to main content

静态资源高效缓存寿命优化

针对 Lighthouse 指出的“使用高效缓存寿命”问题,核心的优化是延长静态资源的缓存时间(TTL)。你提到的 logo.svg 文件是一个很好的切入点。

问题所在:7天的缓存寿命不够长

Lighthouse 的建议是将静态资源的缓存时间尽可能地延长。你报告中 logo.svg 的缓存寿命(TTL)是 7天,这通常不足以让 Lighthouse 的审计认为它是“高效”的。

一个更优的缓存策略是,为这类几乎不会变动的静态资源(如Logo、CSS、JS库)设置以“年”为单位的缓存时间,例如 max-age=31536000(即一年)。这能让网站在用户重复访问时实现“零请求”加载,从而可能节省你报告中提到的 475 KiB 的传输量。


优化方案:为不同资源设置分层缓存策略

一个高效的缓存策略应该根据资源的更新频率来“分层”设置。

1. 长期缓存策略(针对 logo.svg 等静态资源)

  • 适用资源logo.svg*.css*.js、字体文件等不常变更的静态资源。
  • 推荐配置
    • 响应头Cache-Control: public, max-age=31536000, immutable
    • 参数解读
      • public: 允许浏览器和任何中间代理(如CDN)缓存该资源。
      • max-age=31536000: 设置缓存时长为1年(31536000秒)。
      • immutable: 告诉浏览器,在缓存过期前,永远不要向服务器发起请求来验证资源是否更新。

2. 版本化文件名(关键配套措施)

这是实现长期缓存的关键。如果文件内容更新了,但浏览器仍使用长达一年的缓存,用户将无法看到新内容。

  • 最佳实践:在构建或部署时,为文件名加上内容哈希值(Content Hash)
  • 示例:将 logo.svg 更新为 logo.a1b2c3d4.svg
  • 效果:文件内容变化 → 哈希值变化 → URL变化 → 浏览器视为全新资源,立即从服务器获取。旧文件则继续存在于缓存中,不会造成任何问题。

3. 短期或协商缓存策略(针对HTML等入口文件)

  • 适用资源index.html 等入口文件。
  • 推荐配置
    • 响应头Cache-Control: no-cache, must-revalidate
    • 解读:这并非禁止缓存,而是要求浏览器每次使用前都必须向服务器验证资源是否更新。
    • 机制:服务器通过 ETagLast-Modified 响应头来验证。
    • 效果:如果内容未变,服务器返回 304 Not Modified 状态码,浏览器使用本地缓存,传输量极小;如果内容已更新,则返回新文件。

如何实施

配置方法取决于你的技术栈:

  • 如果你使用 Nginx:可以参考以下配置:
    # 针对带哈希的文件,设置1年 + immutable 缓存
    location ~* "\.[a-f0-9]{8,}\.(css|js|svg|png|jpg|jpeg|gif|webp|ico|woff|woff2)$" {
    add_header Cache-Control "public, max-age=31536000, immutable" always;
    }
    # 针对无哈希的静态资源(如 logo.svg),设置30天缓存(若无法添加哈希)
    location ~* \.(css|js|png|jpg|jpeg|gif|svg|webp|ico|woff|woff2)$ {
    add_header Cache-Control "public, max-age=2592000" always;
    }
  • 如果你使用 CDN:在 CDN 的缓存策略中,为静态资源路径(如 /static/*)设置相同的 Cache-Control 响应头。
  • 如果你使用云存储(如 AWS S3):可以为文件设置自定义的元数据(Metadata),添加 Cache-Control 头。

如何验证

  • 使用浏览器的开发者工具 (DevTools) 中的 Network(网络) 面板。
  • 刷新页面,查看静态资源的 Response Headers(响应头),确认 Cache-Control 是否已更新。
  • 对于已缓存的资源,状态码会显示为 200 (from disk cache)304 Not Modified

总结与后续建议

  1. 立即优化:将 logo.svg 的缓存时间从7天延长至至少30天,如果可能,配合版本化文件名设置为1年
  2. 系统性排查:检查网站上所有静态资源(CSS、JS、图片等)的缓存头,对它们应用分层缓存策略。
  3. 建立机制:将“版本化文件名”作为前端构建流程的标准环节,这样就能安全地对大部分资源设置超长的缓存时间。

通过实施以上方案,你不仅能解决 Lighthouse 指出的问题,还能显著提升重复访客的加载体验,并有效节省带宽。