前端面经 强缓存与协商缓存
图片多来自第三方平台
文章目录
- 前端面经 强缓存与协商缓存
- 适用场合
- 浏览器缓存的过程
- 缓存规则
- 强缓存(本地缓存)
- 协商缓存
缓存分为两种:强缓存和协商缓存,根据响应的header内容来决定
获取资源形式 | 状态码 | 发送请求到服务器 | |
---|---|---|---|
强缓存 | 从缓存取 | 200(from cache) | 否,直接从缓存取 |
协商缓存 | 从缓存取 | 304(not modified) | 是,通过服务器来告知缓存是否可用 |
强缓存相关字段有expires
,cache-control
。如果cache-control
与expires
同时存在的话,cache-control
的优先级高于expires
。
协商缓存相关字段有Last-Modified/If-Modified-Since
,Etag/If-None-Match
适用场合
因为服务器上的资源不是一直固定不变的,大多数情况下它会更新,这个时候如果我们还访问本地缓存,那么对用户来说,相当于资源没有更新,用户看到的还是旧的资源
所以我们希望服务器上的资源更新,浏览器就请求新的资源,没有更新就使用本地的缓存,以最大程度的减少因网络请求而产生的资源浪费
浏览器缓存的过程
-
在浏览器第一次发起请求时,本地无缓存,向web服务器发送请求,服务器响应请求,浏览器缓存。过程入下:
在第一次请求时,服务器会将页面最后修改时间通过Last-Modified
标识由服务器发送给客户端,客户端记录时间;服务器还会生成一个Etag
,并发送给客户端 -
浏览器后续再次进行请求时:
- 浏览器在请求某一资源时,会线获取该资源缓存的header信息,判断是否命中强缓存(是否由
cache-control
和expires
信息),若命中则根据cache-control
的max-age
判断是否过期,没有过期直接从缓存中获取资源信息,包括缓存header
信息;本次请求根本就不会与服务器进行通信 - 如果没有命中强缓存,或缓存过期。浏览器会发送请求到服务器,请求会携带第一次请求返回的有关缓存的header字段信息(
Last-Modified/If-Modified-Since
和Etag/If-None-Match
),由服务器根据请求中的相关header
信息来比对结果是否协商缓存命中;- 若命中(
requst header
返回的If-None-Match
和If-Modified-Since
与服务器的Etag
和Last-Modified
相同),则服务器返回新的响应header
信息更新缓存中的对应header
信息,但是并不返回资源内容,它会告知浏览器可以直接从缓存获取 - 否则返回最新的资源内容
- 若命中(
304:如果客户端发送了一个带条件的GET请求且该请求已被允许,而文档的内容(自上次访问以来或根据请求的条件)并没有改变,则服务器应当返回304状态码
缓存规则
强缓存(本地缓存)
直接从缓存中获取资源而不经过服务器,前提是资源没过期。
即如果资源没过期,就取缓存,如果过期了,则请求服务器。
如何判断资源是否过期呢,也就是说强缓存的规则怎么看?
主要是看response header
中的Cache-Control
Cache-Control设定值:
- max-age=xxx:过期时间
- no-cache:不使用强缓存(本地缓存)。需要使用缓存协商,先与服务器确认返回的响应是否被更改,如果之前的响应中存在ETag,那么请求的时候会与服务端验证,如果资源未被更改,则可以避免重新下载。
- no-store:不强缓存,也不协商缓存。直接禁止浏览器缓存数据,每次请求资源都会向服务器发送一个请求,每次都会下载完整的资源
- public:浏览器和CDN等中间代理服务器都可以缓存
- private:仅服务器缓存,不允许CDN等中继缓存服务器对其缓存
缓存保存的位置:
- 内存缓存:具有两个特点,分别是快速读取和时效性
- 快速读取:内存缓存会将百衲衣解析后的文件,直接存入进程的内存,占据该进程一定的内存资源,以方便下次运行使用时的快速读取
- 时效性:一旦该进程关闭,则该进程的内存则会清空
- 硬盘缓存:硬盘缓存则时直接将缓存写入硬盘文件中,读取缓存需要对该缓存存放的硬盘进行I/O操作,然后重新解析该缓存内容,读取复杂,速度比内存缓存慢
在浏览器中,浏览器会在js和图片等文件解析执行后直接存入 内容缓存,那么当刷新页面时只需直接从内存缓存中读取
css文件则会存入硬盘文件中,所以每次渲染页面都需要从硬盘读取缓存
协商缓存
触发条件:
Cache-Control
的值为no-cache
(不强缓存)- 或者
max-age
过期
图中,虽然强缓存命中,但是也有ETag
和Last-Modified
,这两个就是协商缓存相关规则
Etag:服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定)
If-None-Match:当资源过期时(使用Cache-Control
标识的max-age
),发现资源具有ETag
声明,则再次向服务器请求时带上头If-None-Match
(ETag
的值)。服务器收到请求后发送头If-None-Match
则于被请求资源的相应校验串进行比对,决定是否协商缓存