对我们前端来说,了解web的缓存机制是重中之重,今天就一起来巩固一下。
1. HTTP 缓存的好处
HTTP 缓存机制带来了多重好处,主要包括:
- 减少冗余的数据传输: 缓存机制使得客户端能够直接从本地获取资源,减少了不必要的网络请求,从而节省了带宽费用。
- 减轻服务器压力: 通过减少对服务器的请求频率,缓存可以有效减轻服务器的负担,从而提升整体性能。
- 降低延迟和网络阻塞: 通过使用缓存,用户可以更快地加载页面,降低了网络延迟和阻塞现象。
- 加快网页加载速度: 更快的资源获取意味着用户能更流畅地体验网页。
2. 常见的 HTTP 缓存类型
了解缓存的类型有助于更好地管理和使用缓存,常见的类型包括:
- 私有缓存: 通常是指用户本地的浏览器缓存,只能被特定用户访问。
- 代理缓存: 中间服务器(如 CDN)所缓存的资源,可以被多个用户共享。
3. 本地缓存详解
本地缓存指的是当浏览器请求资源时,如果之前的请求已命中缓存,浏览器将直接使用本地缓存,而不会向服务器发送请求。其执行过程如下:
- 第一次请求:
- 浏览器向服务器发起请求,服务器返回资源,响应码为200 OK。浏览器将资源和响应头一起缓存。
- 第二次请求:
- 在请求前,浏览器检查上一次响应头的信息中的
Cache-Control
。根据其值(通常为相对值,单位为秒),浏览器判断缓存的有效期。 - 如果缓存未过期,则直接使用缓存;如果过期,则发起新的请求,并进入缓存协商阶段。
- 在请求前,浏览器检查上一次响应头的信息中的
3.1 Cache-Control 头
Cache-Control
是 HTTP 缓存策略中最重要的头部字段,它的值可以包括:
- no-cache: 不使用本地缓存,需与服务器确认响应是否更改。
- no-store: 禁止浏览器缓存数据,每次请求都需从服务器获取资源。
- public: 可被所有用户缓存,包括终端用户和代理服务器。
- private: 仅允许终端用户的浏览器缓存。
- max-age: 从请求开始,允许的最大缓存时间(以秒为单位)。
- must-revalidate: 缓存过期时需去服务器校验。
3.2 Expires 头
Expires
是 HTTP/1.0 中引入的头部字段,用于设置本地缓存的绝对有效时间。格式为 Mon, 10 Jun 2015 21:31:12 GMT
。当请求时间在 Expires
时间之前,缓存有效;否则需向服务器请求更新的资源。
3.3 缓存协商
当第二次请求发生时,如果没有有效的缓存,浏览器将与服务器进行缓存协商,流程如下:
- 如果没有
Cache-Control
或其过期,或者Cache-Control
设置为no-cache
,浏览器会询问服务器缓存资源是否为旧版本。 - 服务器通过
Last-Modified/If-Modified-Since
或ETag/If-None-Match
来判断资源是否更新。 - 若未更新,返回304 Not Modified;若更新,返回200 OK及最新资源。
3.4 Last-Modified 与 If-Modified-Since
- Last-Modified: 服务器返回资源的最后修改时间。
- If-Modified-Since: 浏览器在第二次请求时,将最后修改时间发送给服务器进行比对。
3.5 ETag 与 If-None-Match
为了避免精度问题,HTTP 还引入了 ETag
和 If-None-Match
,通过资源的哈希值来判断缓存的有效性:
- ETag: 资源的唯一标识符,基于内容的摘要信息。
- If-None-Match: 浏览器在请求中发送的 ETag 值,与服务器的当前值进行比较。
4. 缓存位置
浏览器缓存的存储位置可以分为四种,优先级从高到低为:
- Service Worker: 允许离线缓存和消息推送。
- Memory Cache: 内存中的缓存,速度最快但存活时间最短。
- Disk Cache: 磁盘中的缓存,存储时间较长,但速度慢于内存。
- Push Cache: HTTP/2 的内容推送缓存。
5. 总结
浏览器缓存分为强缓存和协商缓存。强缓存通过 HTTP 头部直接判断是否命中,而协商缓存则需要与服务器进行验证。了解这两种缓存机制的工作原理,能帮助开发者更好地优化网页性能。
- 强缓存:
- Expires: 绝对时间。
- Cache-Control: max-age。
- 协商缓存:
- Last-Modified 和 If-Modified-Since。
- ETag 和 If-None-Match。