一、浏览器缓存的原理
浏览器缓存分为强缓存和协商缓存:
- 强缓存:浏览器直接用本地缓存,不发请求到服务器(如
Cache-Control: max-age
、Expires
)。 - 协商缓存:浏览器带上缓存标识(如
If-Modified-Since
、If-None-Match
),服务器判断资源是否变更,未变更返回304,浏览器用本地缓存。
二、Nginx配置浏览器缓存
1. 设置强缓存(推荐)
location ~* \.(js|css|png|jpg|jpeg|gif|ico|woff|woff2|ttf|svg)$ {
expires 30d;
add_header Cache-Control "public, max-age=2592000";
}
expires 30d;
:设置资源30天后过期Cache-Control: public, max-age=2592000
:2592000秒=30天
2. 设置协商缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|woff|woff2|ttf|svg)$ {
add_header Last-Modified $date_gmt;
add_header ETag $upstream_http_etag;
if_modified_since exact;
etag on;
}
- 浏览器下次请求会带
If-Modified-Since
和If-None-Match
,服务器判断是否返回304
三、Apache配置浏览器缓存
1. 设置强缓存
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access plus 30 days"
ExpiresByType image/jpeg "access plus 30 days"
ExpiresByType image/gif "access plus 30 days"
ExpiresByType image/png "access plus 30 days"
ExpiresByType text/css "access plus 7 days"
ExpiresByType application/javascript "access plus 7 days"
</IfModule>
2. 设置协商缓存
<IfModule mod_headers.c>
Header set Cache-Control "public"
Header set ETag "%{ETAG}e"
</IfModule>
四、前端最佳实践
1. 资源文件名加版本号/哈希
- 每次资源变更,文件名变化,浏览器自动重新下载
- 例如:
main.abc123.js
、style.20240401.css
Webpack配置示例:
output: {
filename: '[name].[contenthash].js',
}
2. HTML引用示例
<link rel="stylesheet" href="style.20240401.css">
<script src="main.abc123.js"></script>
五、常见问题与排查
1. 缓存未生效的表现
- 每次刷新都重新下载静态资源
- Chrome DevTools Network面板,资源
Size
不是(from disk cache)
或(from memory cache)
2. 排查方法
- 用F12打开Network,查看响应头是否有
Cache-Control
、Expires
、Last-Modified
、ETag
- 检查Nginx/Apache配置是否生效
- 检查CDN是否覆盖了源站缓存头
六、缓存策略建议
- 静态资源(图片、JS、CSS、字体):强缓存30天~1年,文件名加哈希
- HTML页面:一般不缓存或短缓存,防止内容过期
- API接口:根据业务需求设置合适的缓存策略
七、完整流程举例
- Nginx/Apache配置强缓存
- 前端构建工具自动加哈希
- HTML引用带哈希的资源
- 上线新版本时,资源名变化,浏览器自动拉新
- 用Chrome DevTools验证缓存命中
八、总结
- 浏览器缓存是提升网站性能的关键手段
- 推荐用强缓存+文件名哈希,保证资源变更即更新,未变更即命中缓存
- 配置简单,效果显著