xb18
xb18
文章39
标签0
分类0
浏览器缓存

浏览器缓存

强缓存和协商缓存

浏览器缓存主要有以下几个优点:

  1. 减少重复数据请求,避免通过网络再次加载资源,节省流量。
  2. 降低服务器的压力,提升网站性能。
  3. 加快客户端加载网页的速度, 提升用户体验。

浏览器缓存分为强缓存和协商缓存,两者有两个比较明显的区别:

  1. 如果浏览器命中强缓存,则不需要给服务器发请求;而协商缓存最终由服务器来决定是否使用缓存,即客户端与服务器之间存在一次通信。
  2. 在 chrome 中强缓存(虽然没有发出真实的 http 请求)的请求状态码返回是 200 (from cache);而协商缓存如果命中走缓存的话,请求的状态码是 304 (not modified)。 不同浏览器的策略不同,在 Fire Fox中,from cache 状态码是 304.

其中 from cache 会分为 from disk cache 和 from memory cache. 从内存中获取最快,但是是 session 级别的缓存,关闭浏览器之后就没有了。

Expires 或者 Cache-Control

请求后缓存资源

客户端请求资源简单过程

首次请求时,服务器返回资源,并在响应头中注明缓存参数,客户端缓存资源 再次请求时,会先访问浏览器缓存,若命中强缓存则直接提取资源,状态码返回 200 若未命中强缓存,则将请求发送给服务器,判断本地协商缓存是否失效,若有效则返回状态码 304 若未命中协商缓存,则服务器返回完整资源,并更新缓存

强缓存

强缓存是根据返回头中的 Expires 或者 Cache-Control 两个字段来控制的,都是表示资源的缓存有效时间。

强缓存的特点是 请求时无需访问服务器 加载速度最快,性能最好 命中时直接返回成功 200 强缓存由响应头中的 Expires 或 Cache-Control 两个字段控制,表示缓存有效期;

Cache-Control

例如:浏览器第一次请求远程服务器的某个资源时,如果服务器希望浏览器得到该资源后一段时间内不要再发送请求过来,直接从浏览器里的缓存里取,则服务器可以通过在响应头里设置Cache-Control: max-age=31536000,max-age代表缓存时间,单位为毫秒,这里的数据换算过来就是一年,意味着在一年内浏览器不会再向服务器发送请求。状态码200。

浏览器缓存资源的地方有两个:磁盘缓存(disk cache)和内存缓存(memory cache)

一般来说,浏览器会将较大的资源缓存到disk cache,而较小的资源则被缓存到memory cache里。内存缓存与磁盘缓存相比,访问速度要更快一些!

Cache-Control除了max-age外,还可以设置其它属性值:

  • no-cache: 不使用强缓存(但仍会使用协商缓存)。
  • no-store: 不使用缓存(不使用强缓存也不使用协商缓存),每次都向服务器发送资源请求。
  • private: 只允许客户端使用缓存,不允许其他代理服务器进行缓存。
  • public: 客户端和代理服务器都可缓存。
  • s-maxage: 与max-age类似,区别是s-maxage是设定代理服务器的缓存时间。

Expires

强缓存除了使用Cache-Control实现之外,还可以使用Expires字段,Expires是Http1.0规范,Cache-Control是Http1.1规范,Expires返回一个具体的时间值,代表缓存的有效期,在该日期内浏览器不会向服务器发起请求,而是直接从缓存里获取资源。

因为Expires参照的是本地客户端的时间,而客户端的时间是可以被修改的,所以会有误差产生的情况,这也是Expires的一个缺点,所以有了后来Http1.1规范的Cache-control

Cache-control的优先级要高于Expires,如果两者同时设置,会优先使用Cache-control而忽略掉Expires。

image-20230902181915789

协商缓存

Etag

协商缓存是由服务器来确定缓存资源是否可用。 主要涉及到两对属性字段,都是成对出现的,即第一次请求的响应头带上某个字, Last-Modified 或者 Etag,则后续请求则会带上对应的请求字段 If-Modified-Since或者 If-None-Match,若响应头没有 Last-Modified 或者 Etag 字段,则请求头也不会有对应的字段。

未命中强缓存时,需访问服务器确认当前浏览器的缓存是否过期,若未过期则直接读取,返回 304

例如:浏览器初次请求资源,服务器返回资源,同时生成一个Etag值携带在响应头里返回给浏览器,当浏览器再次请求资源时会在请求头里携带If-None-Match,值是之前服务器返回的Etag的值,服务器收到之后拿该值与资源文件最新的Etag值做对比。

Last-Modified

除了Etag外,还有一个Last-Modified的属性,它是Http1.0规范的,服务器返回Last-Modified,浏览器请求头对应携带的是If-Modified-since,与Etag不同的是,Last-Modified的值是一个时间值,代表文件的修改时间,服务器通过对比文件的修改时间是否发生改变来判断是否使用缓存

相比Last-ModifiedEtag优先级更高,使用上也更精确一些,因为有时候会存在文件内容并没有改变,但文件的修改时间变更了,Last-Modified不一致所以服务器会重新返回资源文件,实际上还是可以继续使用缓存的。

image-20230902185647767

image-20230902185703433

优先级

强缓存优先级大于协商缓存,即两者同时存在时,如果强缓存开启且在有效期内,则不会走协商缓存。

原生开发中静态资源缓存问题

URL添加时间戳或者随机数

1
2
var timestamp = new Date().getTime(); // 获取当前时间戳  Math.random() 随机数
var url = "example.com/a.js?t=" + timestamp;
本文作者:xb18
本文链接:http://xb18.github.io/2023/01/23/%E6%B5%8F%E8%A7%88%E5%99%A8%E7%BC%93%E5%AD%98/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可