一、缓存策略分类与应用场景
针对不同类型的前端资源(HTML、CSS、JS、图片、文本),需根据资源特性和更新频率制定差异化的缓存策略:
资源类型 | 缓存策略 | 典型配置 | 说明 |
---|---|---|---|
HTML | 协商缓存(Cache-Control: no-cache) | ETag + Last-Modified | HTML 通常包含动态内容,需每次验证是否更新,避免强缓存导致页面不刷新。 |
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)
- ETag 与 Last-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 验证
}
四、缓存策略优化与注意事项
-
避免缓存陷阱:
- 不要对 HTML 页面设置过长的强缓存(如 1 年),否则更新后用户无法立即看到新内容。
- 动态内容(如用户个人信息)必须禁用缓存(
Cache-Control: no-store
)。
-
缓存验证机制:
- 协商缓存通过
ETag
和Last-Modified
实现:- 客户端请求时携带
If-None-Match
(ETag 值)和If-Modified-Since
; - 服务器对比后,若资源未修改则返回
304 Not Modified
。
- 客户端请求时携带
- 协商缓存通过
-
Service Worker 最佳实践:
- 仅缓存静态资源,避免缓存动态 API 数据。
- 使用
Cache-first
策略缓存 CSS/JS/图片,Network-first
策略处理实时数据。
-
性能监控:
- 通过浏览器开发者工具(如 Chrome 的 Network 面板)检查资源的缓存状态(如
disk cache
、memory cache
)。
- 通过浏览器开发者工具(如 Chrome 的 Network 面板)检查资源的缓存状态(如
五、问题
1. 问:如何处理 CSS/JS 文件更新后用户缓存未失效的问题?
- 答:
- 使用文件名哈希(如
app.7f8c.js
),内容变更时哈希值变化,强制客户端加载新资源。 - 确保 HTML 文件不被强缓存(设置
Cache-Control: no-cache
),以便每次加载最新的资源引用。
- 使用文件名哈希(如
2. 问:CDN 如何影响缓存策略?
- 答:
- CDN 通常默认缓存静态资源(如 CSS/JS/图片),需通过 HTTP 头控制 CDN 缓存时间(如
Cache-Control: max-age=31536000
)。 - CDN 缓存刷新需通过其管理界面手动触发(如“缓存刷新”操作)。
- CDN 通常默认缓存静态资源(如 CSS/JS/图片),需通过 HTTP 头控制 CDN 缓存时间(如
3. 问:Service Worker 与 HTTP 缓存的关系?
- 答:
- Service Worker 优先级高于 HTTP 缓存,可完全拦截网络请求并自定义响应逻辑。
- 两者可结合使用:Service Worker 缓存静态资源,HTTP 缓存控制动态内容。
六、总结
“前端缓存策略需根据资源类型和更新频率分场景配置:HTML 采用协商缓存确保实时性,CSS/JS/图片通过文件名哈希和长时效强缓存提升加载速度,动态数据则根据更新频率设置合理的缓存时间。同时,可结合 Service Worker 实现离线缓存,进一步优化用户体验。在实际项目中,需通过开发者工具监控缓存效果,并注意避免因缓存配置不当导致的更新延迟问题。”