文章目录
作为前端开发者,理解 缓存命中(Cache Hit) 非常重要,尤其在你处理性能优化、资源加载、用户体验提升、离线支持等方面。
一、什么是缓存命中?
缓存命中(Cache Hit) 指当你请求某个资源(比如图片、JS 文件、API 响应等)时,浏览器或其他中间层发现缓存中已有该资源,于是直接返回缓存结果,而不需要再去网络请求。
这样做有两个好处:
- 提升加载速度:从缓存读取远比从网络拉取快得多。
- 减少服务器压力:命中缓存后不发起请求,减轻后端负担。
二、前端开发要知道哪些缓存机制(以及命中条件)?
前端缓存机制主要分为两大类:浏览器缓存(静态资源) 和 应用层缓存(数据、状态)。
1. 浏览器缓存(主要针对静态资源)
常见的缓存位置
- 内存缓存(Memory Cache):短期缓存,刷新页面即失效。
- 磁盘缓存(Disk Cache):持久性更强,关闭浏览器后依然有效。
- Service Worker 缓存:你控制的离线缓存,可以精细化管理。
- Push Cache(HTTP/2):很短暂,针对同一次会话的缓存。
关键 HTTP 头字段(决定命中与否)
字段 | 作用 | 示例 |
---|---|---|
Cache-Control |
控制是否缓存、缓存时长 | max-age=3600 , no-cache |
ETag |
内容标识符,用于比较是否更新 | ETag: "abc123" |
Last-Modified |
上次修改时间 | Last-Modified: Wed, 01 May 2024 12:00:00 GMT |
Expires |
绝对过期时间(已被 Cache-Control 替代) | Expires: Tue, 21 May 2025 08:00:00 GMT |
命中机制简化流程:
浏览器请求资源。
如果缓存未过期(如
max-age
生效) → 强缓存命中(直接使用缓存)。如果缓存过期 → 浏览器发送带上
If-None-Match
(对比ETag
)或If-Modified-Since
(对比修改时间)。- 若内容没变,服务器返回
304 Not Modified
→ 协商缓存命中。 - 否则重新返回新资源。
- 若内容没变,服务器返回
2. 前端应用层缓存(例如数据请求)
用于缓存 API 请求或状态数据,例如:
localStorage
/sessionStorage
:持久化存储。IndexedDB
:复杂结构、本地数据库。- 前端框架内缓存:如 React Query、SWR、Apollo Client 等。
例如在 SWR 中,数据缓存命中机制基于 key-value 和 revalidation 策略:
const { data } = useSWR('/api/user', fetcher)
- 再次访问相同 key(URL)→ 命中缓存。
- 根据配置决定是否 revalidate(重新请求)。
三、前端开发者需要掌握哪些实践?
浏览器缓存策略实战建议
设置合理的 Cache-Control
- JS/CSS 设置长时间缓存:
Cache-Control: public, max-age=31536000, immutable
- HTML 页面设置短时间缓存 + 协商缓存:
no-cache
- JS/CSS 设置长时间缓存:
使用文件哈希名作为缓存破坏手段(Cache Busting)
- 比如:
main.3f3c1f.js
,文件变了名字也变了,浏览器会重新加载。
- 比如:
服务端正确返回 ETag/Last-Modified
- 保证协商缓存生效,减少带宽开销。
数据缓存建议
- 用 SWR、React Query 等库管理 API 缓存。
- 配合缓存时间和 revalidation 策略(如
stale-while-revalidate
)。 - 结合 localStorage / IndexedDB 实现离线缓存支持。
四、如何判断资源是否命中缓存?
打开浏览器开发者工具(DevTools):
刷新页面
Network 面板查看请求
看
Status
和Size
列:200 (from disk cache)
:磁盘缓存命中200 (from memory cache)
:内存缓存命中304 Not Modified
:协商缓存命中
五、缓存未命中
缓存未命中(Cache Miss) 是指在系统尝试从缓存中读取数据时,未找到所需数据,因此需要从更慢的存储介质(比如内存或硬盘)中加载数据的情况。
这会导致访问延迟增加,是性能优化中需要重点关注的问题。
缓存未命中通常分为以下几种类型:
强制未命中(Compulsory Miss)
- 也叫冷启动未命中,是指某个数据首次被访问时,由于之前从未加载过,所以缓存中自然没有,必须从原始数据源加载。
容量未命中(Capacity Miss)
- 缓存容量不足,无法容纳所有活跃数据,因此部分数据被替换,后续访问这些数据时就会发生未命中。
冲突未命中(Conflict Miss)
- 在组相联缓存或直接映射缓存中,不同的数据映射到了同一个缓存位置,导致彼此竞争位置并被替换,从而造成未命中。
举个例子:假设你打开了一个网页,网页上的某张图片之前没有加载过——这时候浏览器会从服务器下载图片并缓存起来。这就是强制未命中。下次你再次访问该页面,如果缓存被清除或图片被替换掉了,再加载时就可能是容量未命中或冲突未命中。
总结
缓存命中是前端性能优化的核心手段之一,理解浏览器缓存机制、合理配置 HTTP 头信息、结合应用层缓存工具,可以极大提升用户体验。