什么是强制缓存(强缓存)?
1. 强制缓存的原理
- 当用户首次访问网页时,浏览器会向服务器请求资源(如 CSS、JS、图片)。
- 服务器在返回资源时,会附带 Cache-Control 或 Expires 头部,告诉浏览器这个资源可以被缓存,以及缓存的有效期。
- 在缓存有效期内,浏览器会直接使用本地缓存,而不会向服务器发起请求,从而加快页面加载速度。
2. 强制缓存的实现方式
(1) Cache-Control 头
Cache-Control 是 HTTP/1.1 规范中用于控制缓存的主要方式,它可以通过 max-age 指定资源在缓存中的存活时间。
Cache-Control: public, max-age=31536000, immutable
- public:允许所有用户(包括 CDN)缓存资源。
- max-age=31536000(1年):资源在31536000 秒内(1 年)都是有效的,浏览器在此期间不会向服务器请求资源。
- immutable:即使用户刷新页面,也不会重新请求这个资源(适用于不会变化的资源,如版本化的 JS 文件 app.abc123.js)。
示例:Nginx 配置
location /static/ {
expires 1y;
add_header Cache-Control "public, max-age=31536000, immutable";
}
(2) Expires 头(HTTP/1.0 方式,已被 Cache-Control 取代)
Expires 指定资源过期的绝对时间,浏览器在这个时间之前不会重新请求资源:
Expires: Wed, 21 Oct 2025 07:28:00 GMT
- 但如果用户本地时间错误,Expires 可能会失效,因此现代浏览器更推荐 Cache-Control。
3. 强制缓存的特点
优点:
- 减少 HTTP 请求,提升性能,适用于不经常变动的静态资源(如图片、字体、CSS、JS)。
- 即使用户刷新页面,资源仍然从缓存中加载,特别是 immutable 让资源“永久缓存”。
缺点:
- 资源更新问题:如果资源变更(如 app.js 更新),但浏览器仍然使用缓存,用户可能无法获取最新版本。
- 解决方案:使用版本号或哈希值来区分不同版本,如 app.abc123.js。
4. 强缓存 vs 协商缓存
对比项 | 强制缓存(强缓存) | 协商缓存(对比缓存) |
是否请求服务器 | 不会 ,直接使用本地缓存 | 会发送请求 ,但可能返回 304 Not Modified |
缓存控制方式 | Cache-Control: max-age=xxx 、Expires | ETag 、Last-Modified |
适用场景 | 静态资源(JS、CSS、图片) | 可能会更新的资源 |
资源更新方式 | 依赖 max-age,需要手动更改 URL | 服务器检测是否有更新 |
是否适合频繁变化资源 | 不适合 (需要版本控制) | 适合 (服务器决定是否返回新资源) |
5. 面试官可能的延伸问题
面试官:如何让静态资源始终走强制缓存?
回答:在服务器配置 Cache-Control: max-age=31536000, immutable,让资源缓存 1 年且不可更改。同时,为了避免缓存过期问题,采用文件指纹(hash)版本控制,如:
<scriptsrc="/static/app.abc123.js"></script>
面试官:强制缓存 vs 协商缓存,哪个性能更好?
回答:强制缓存性能更好,因为浏览器不会发送请求。但它不适用于需要频繁更新的资源,而协商缓存允许服务器判断资源是否更新,适用于动态内容。
面试官:如何让 index.html 始终最新,而 JS/CSS 走强制缓存?
回答:
- **index.html 设置 Cache-Control: no-cache, must-revalidate**,保证浏览器每次访问都向服务器请求最新的 HTML。
- **JS/CSS 资源使用 max-age=31536000, immutable**,并使用文件版本哈希:
<scriptsrc="app.abc123.js"></script>
<linkrel="stylesheet"href="styles.456def.css">
面试官:用户访问了旧版本的缓存文件,如何让他强制刷新?
回答:
- 更改文件名(带 hash)app.abc123.js → app.def456.js。
- **后端返回 Cache-Control: no-cache 或 ETag**,让浏览器重新检查更新。
- 前端通知用户刷新(Service Worker + 版本检测):
if ("serviceWorker"in navigator) {
navigator.serviceWorker.register("/sw.js").then(reg => {
reg.addEventListener("updatefound", () => {
console.log("发现新版本,建议刷新页面");
});
});
}
6. 总结
“强制缓存(强缓存)是一种浏览器缓存策略,它通过 Cache-Control: max-age=xxx 或 Expires 让浏览器在缓存有效期内直接使用本地缓存,而不发送请求。这样可以减少 HTTP 请求,提高页面性能。相比之下,协商缓存(如 ETag 和 Last-Modified)会向服务器询问资源是否更新。如果希望资源强制缓存但又能及时更新,可以结合文件指纹(hash)和版本控制。”
这样回答,既清楚解释了强缓存原理,又能结合实际优化方案,面试官一定会认可你的专业性!