HTTP 缓存
什么是浏览器缓存
浏览器缓存其实就是浏览器保存通过 HTTP 获取的所有资源,是浏览器将网络资源存储在本地的一种行为
三级缓存原理
- 先在内存中查找,如果有,直接加载。
- 如果内存中不存在,则在硬盘中查找,如果有直接加载。
- 如果硬盘中也没有,那么就进行网络请求。
- 请求获取的资源缓存到硬盘和内存。
浏览器缓存的分类
- 强缓存
- 协商缓存
浏览器再向服务器请求资源时,首先判断是否命中强缓存,再判断是否命中协商缓存!
获取资源形式 | 状态码 | 发送请求到服务器 | |
---|---|---|---|
强缓存 | 缓存 | 200(from cache) | 否,直接从缓存取 |
协商缓存 | 缓存 | 304(not modified) | 是,通过服务器来告知缓存是否可用 |
强缓存
浏览器在加载资源时,会先根据本地缓存资源的 header 中的信息判断是否命中强缓存,如果命中则直接使用缓存中的资源不会再向服务器发送请求。
这里的 header 中的信息指的是 expires 和 cahe-control.
Cache-Control 与 Expires 可以在服务端配置同时启用,同时启用的时候 Cache-Control 优先级高
Expires
该字段是 http1.0 时的规范,它的值为一个绝对时间的 GMT 格式的时间字符串,比如 Expires:Mon,18 Oct 2066 23:59:59 GMT。这个时间代表着这个资源的失效时间,在此时间之前,即命中缓存。这种方式有一个明显的缺点,由于失效时间是一个绝对时间,所以当服务器与客户端时间偏差较大时,就会导致缓存混乱。
Cache-Control
Cache-Control 是 http1.1 时出现的 header 信息,主要是利用该字段的 max-age 值来进行判断,它是一个相对时间,例如 Cache-Control:max-age=3600,代表着资源的有效期是 3600 秒。
no-store
响应不被缓存
彻底禁用缓冲,所有内容都不会被缓存到缓存或临时文件中。no-cache
每次在向客户端(浏览器)提供响应数据时,缓存都要向服务器评估缓存响应的有效性
在浏览器使用缓存前,会往返对比 ETag,如果 ETag 没变,返回 304,则使用缓存public
所有内容都将被缓存(客户端和代理服务器都可缓存)private
内容只缓存到私有缓存中(仅客户端可以缓存,代理服务器不可缓存)max-age=xxx
缓存的内容将在 xxx 秒后失效,这个选项只在 HTTP1.1 可用,并如果和Last-Modified
一起使用时,优先级较高。
协商缓存
当强缓存没有命中的时候,浏览器会发送一个请求到服务器,服务器根据 header 中的部分信息来判断是否命中缓存。如果命中,则返回 304 ,告诉浏览器资源未更新,可使用本地的缓存。
这里的 header 中的信息指的是 Last-Modify/If-Modify-Since
和 ETag/If-None-Match
。
Last-Modify/If-Modify-Since
浏览器第一次请求一个资源的时候,服务器返回的 header 中会加上 Last-Modify
,Last-modify
是一个时间标识该资源的最后修改时间。
当浏览器再次请求该资源时,request 的请求头中会包含 If-Modify-Since,该值为缓存之前返回的 Last-Modify
。服务器收到 If-Modify-Since
后,根据资源的最后修改时间判断是否命中缓存。
如果命中缓存,则返回 304,并且不会返回资源内容,并且不会返回 Last-Modify
。
缺点:
短时间内资源发生了改变,Last-Modified
并不会发生变化。
周期性变化。如果这个资源在一个周期内修改回原来的样子了,我们认为是可以使用缓存的,但是 Last-Modified 可不这样认为,因此便有了 ETag。
ETag/If-None-Match
与 Last-Modify/If-Modify-Since
不同的是,Etag/If-None-Match
返回的是一个校验码。ETag 可以保证每一个资源是唯一的,资源变化都会导致 ETag 变化。服务器根据浏览器上送的 If-None-Match 值来判断是否命中缓存。
与 Last-Modified
不一样的是,当服务器返回 304 Not Modified
的响应时,由于 ETag 重新生成过,response header 中还会把这个 ETag 返回,即使这个 ETag 跟之前的没有变化。
Last-Modified
与 ETag 是可以一起使用的,服务器会优先验证 ETag,一致的情况下,才会继续比对 Last-Modified
,最后才决定是否返回 304。
浏览器缓存的优点
减少了冗余的数据传输
减少了服务器的负担,大大提升了网站的性能
加快了客户端加载网页的速度