前端资源缓存策略

4 阅读4分钟

一、缓存策略分类与应用场景

针对不同类型的前端资源(HTML、CSS、JS、图片、文本),需根据资源特性和更新频率制定差异化的缓存策略:

资源类型缓存策略典型配置说明
HTML协商缓存(Cache-Control: no-cache)ETag + Last-ModifiedHTML 通常包含动态内容,需每次验证是否更新,避免强缓存导致页面不刷新。
CSS/JS强缓存(长时效) + 文件名哈希Cache-Control: max-age=31536000通过哈希版本号(如 app.7f8c.js)确保更新时客户端强制加载新资源。
图片/字体强缓存(长时效)Cache-Control: max-age=31536000静态资源更新频率低,可长期缓存,通过更新文件名触发缓存失效。
文本数据协商缓存或中等时效强缓存Cache-Control: max-age=600如 API 返回的 JSON 数据,根据更新频率设置合理的缓存时间(如 10 分钟)。

二、核心缓存控制方法

1. HTTP 缓存头(优先级从高到低)
  • Cache-Control(HTTP/1.1):
    Cache-Control: max-age=3600       # 资源缓存 1 小时(3600 秒)  
    Cache-Control: no-cache           # 强制协商缓存(需验证后使用)  
    Cache-Control: no-store           # 禁止任何缓存(如敏感数据)  
    
  • Expires(HTTP/1.0):
    Expires: Wed, 21 Oct 2025 07:28:00 GMT  # 资源过期时间(绝对时间,优先级低于 Cache-Control)  
    
  • ETagLast-Modified
    ETag: "5f8c1d69-3e7a"              # 资源内容哈希值,用于协商缓存验证  
    Last-Modified: Tue, 15 Sep 2020 12:00:00 GMT  # 资源最后修改时间  
    
2. 文件名哈希(版本控制)
  • 通过 Webpack 等工具为静态资源生成哈希文件名(如 app.7f8c.js),当内容变更时哈希值变化,强制客户端加载新资源。
  • 示例配置(Nginx)
    location ~* \.(js|css|png|jpg|woff2)$ {
        expires 1y;                     # 强缓存 1 年  
        add_header Cache-Control "public";  
    }
    
3. Service Worker(离线缓存)
  • 拦截网络请求,自定义缓存策略(如缓存优先、网络优先):
    self.addEventListener('fetch', (event) => {
      event.respondWith(
        caches.match(event.request)
          .then((cachedResponse) => {
            // 缓存优先策略
            return cachedResponse || fetch(event.request);
          })
      );
    });
    

三、不同资源的具体配置示例

1. HTML 文件(协商缓存)
location = /index.html {
    add_header Cache-Control "no-cache";  # 每次请求都验证资源  
    etag on;                              # 启用 ETag 验证  
}
2. 静态资源(CSS/JS/图片)
# 静态资源目录
location /static/ {
    expires 1y;                          # 强缓存 1 年  
    add_header Cache-Control "public";  
    access_log off;                      # 关闭访问日志,减轻服务器负担  
}
3. API 数据(协商缓存)
location /api/ {
    expires 5m;                          # 缓存 5 分钟  
    add_header Cache-Control "public, max-age=300";  
    etag on;                             # 配合 ETag 验证  
}

四、缓存策略优化与注意事项

  1. 避免缓存陷阱

    • 不要对 HTML 页面设置过长的强缓存(如 1 年),否则更新后用户无法立即看到新内容。
    • 动态内容(如用户个人信息)必须禁用缓存(Cache-Control: no-store)。
  2. 缓存验证机制

    • 协商缓存通过 ETagLast-Modified 实现:
      • 客户端请求时携带 If-None-Match(ETag 值)和 If-Modified-Since
      • 服务器对比后,若资源未修改则返回 304 Not Modified
  3. Service Worker 最佳实践

    • 仅缓存静态资源,避免缓存动态 API 数据。
    • 使用 Cache-first 策略缓存 CSS/JS/图片,Network-first 策略处理实时数据。
  4. 性能监控

    • 通过浏览器开发者工具(如 Chrome 的 Network 面板)检查资源的缓存状态(如 disk cachememory cache)。

五、问题

1. 问:如何处理 CSS/JS 文件更新后用户缓存未失效的问题?
    • 使用文件名哈希(如 app.7f8c.js),内容变更时哈希值变化,强制客户端加载新资源。
    • 确保 HTML 文件不被强缓存(设置 Cache-Control: no-cache),以便每次加载最新的资源引用。
2. 问:CDN 如何影响缓存策略?
    • CDN 通常默认缓存静态资源(如 CSS/JS/图片),需通过 HTTP 头控制 CDN 缓存时间(如 Cache-Control: max-age=31536000)。
    • CDN 缓存刷新需通过其管理界面手动触发(如“缓存刷新”操作)。
3. 问:Service Worker 与 HTTP 缓存的关系?
    • Service Worker 优先级高于 HTTP 缓存,可完全拦截网络请求并自定义响应逻辑。
    • 两者可结合使用:Service Worker 缓存静态资源,HTTP 缓存控制动态内容。

六、总结

“前端缓存策略需根据资源类型和更新频率分场景配置:HTML 采用协商缓存确保实时性,CSS/JS/图片通过文件名哈希和长时效强缓存提升加载速度,动态数据则根据更新频率设置合理的缓存时间。同时,可结合 Service Worker 实现离线缓存,进一步优化用户体验。在实际项目中,需通过开发者工具监控缓存效果,并注意避免因缓存配置不当导致的更新延迟问题。”