「浏览器缓存」就这一篇
强缓存
强缓存
是在时效时间内,不走服务端,只走本地缓存
-
expires
-
时间节点,到达这个时间节点,缓存失效,再次请求该资源会从服务器获取;
-
-
cache-control(优先级更高)
-
时间段,从第一获取资源到这个时间段之后,缓存失效,再次请求该资源从服务器获取;例如 ctx.set('Cache-Control', 'max-age=30');
-
public:所有内容都将被缓存(客户端和代理服务器都可缓存)
-
private:所有内容只有客户端可以缓存,Cache-Control的默认取值
-
no-cache:客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定
-
no-store:所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存
-
max-age=xxx (xxx is numeric):缓存内容将在xxx秒后失效
这个地方
no-cache
会带来误解,它并不是不使用缓存,而是不使用强缓存,转而使用协商缓存;no-store
的意思才是不使用缓存。如果同时配置了no-cache和no-store,no-store的优先级要高;
-
-
强缓存时,浏览器会显示 memory cache
或者disk cache
;
一般js、css图片等资源使用强缓存,通过hash值改变实现代码更新;
注:vite中第三方依赖都是强缓存,保证了每次代码更新时候不额外请求依赖库代码;
no-cache 和 no-store
no-cache 和 no-store 用作控制缓存,被服务器通过响应头 Cache-Control 传递给客户端
no-store
永远都不要在客户端存储资源,永远都去原始服务器去获取资源。
no-cache
可以在客户端存储资源,每次都必须去服务端做新鲜度校验,来决定从服务端获取新的资源(200)还是使用客户端缓存(304)。也就是所谓的协商缓存。
一般情况下对于 index.html 或者现代构建环境下不加 hash 的静态资源都需要设置 Cache-Control: no-cache,用来强制每次在服务器端的新鲜度校验。 相当于一下缓存头
Cache-Control: max-age=0, must-revalidate
协商缓存
协商缓存
是要走服务端的,如果请求某个资源,去请求服务端时,发现命中缓存
则返回304
,否则则返回所请求的资源;
-
Last-Modified,If-Modified-Since
对比资源最后一次修改时间,来确定资源是否修改了- 1、第一次请求资源时,服务端会把所请求的资源的
最后一次修改时间
当成响应头中Last-Modified
的值发到浏览器并在浏览器存起来
- 2、第二次请求资源时,浏览器会把刚刚存储的时间当成请求头中
If-Modified-Since
的值,传到服务端,服务端拿到这个时间跟所请求的资源的最后修改时间进行比对
- 3、比对结果如果两个时间相同,则说明此资源没修改过,那就是
命中缓存
,那就返回304
,如果不相同,则说明此资源修改过了,则没命中缓存
,则返回修改过后的新资源
- 1、第一次请求资源时,服务端会把所请求的资源的
-
Etag,If-None-Match(优先级更高)
对比资源内容,来确定资源是否修改- 其实
Etag,If-None-Match
跟Last-Modified,If-Modified-Since
大体一样,区别在于:- 后者是对比资源最后一次修改时间,来确定资源是否修改了
- 前者是对比资源内容,来确定资源是否修改
- 那我们要怎么比对资源内容呢?我们只需要读取资源内容,转成hash值,前后进行比对就行了!!
- 其实
memory cache 和 disk cache
一般情况下,图片对应的是 memory cache,css等资源是 disk cache,js资源即可能是 memory cache,也可能是 disk cache;
disk cache(磁盘缓存) 和 memory cache(内存缓存)的区别
都属于强缓存,现在浏览器缓存存储图像和网页等主要在磁盘上,而操作系统缓存文件可能大部分在内存缓存中。使用这两个缓存功能,是因为它比从远程的 web 服务器获取这些资源的方式更近、更快。同时,memory cache 要比 disk cache 快的多。
总结
如下图,当用户请求数据时首先判断是否有缓存,然后判断缓存是否过期,最后根据判断结果是否去服务器请求数据或者判断本地缓存数据是否能够继续使用;
当读取缓存是优先判断强缓存,强缓存的过程如下图所示,当不满足强缓存时就会走协商缓存;强制缓存优先于协商缓存进行。
强缓存判断逻辑:
- 1、判断cache-control字段,有值;
- 1)当cache-control值为no-store,客户端不能存放缓存,直接请求服务器资源,返回响应200;
- 2)当cache-control值为no-cache,可以在客户端存储资源,每次都必须去服务端做新鲜度校验,来决定从服务端获取新的资源(200)还是使用客户端缓存(304)(也就是所谓的协商缓存逻辑)。
- 3)当当cache-control值为max-age,如果max-age值没过期,直接读取缓存资源,否则判断expires字段;
- 2、无cache-control字段,判断expires字段,有值:
- 1)expries值没过期,直接读取缓存资源;
- 2)expries值过期,走协商缓存判断逻辑;
- 3、无expires字段:走协商缓存的判断逻辑
请求资源返回状态值:
状态 | 类型 | 说明 |
---|---|---|
200 | memory cache | 不访问服务器,直接读缓存,从内存中读取缓存。此时的数据时缓存到内存中的,当kill进程后,也就是浏览器关闭以后,数据将不存在。但是这种方式只能缓存派生资源; |
200 | disk cache | 不请求网络资源(服务器),直接从磁盘中读取缓存,当kill进程时,数据还是存在; |
200 | 资源大小数值 | 从服务器下载最新资源; |
304 | 报文大小 | 请求服务端,返回304,发现资源没更新,然后从缓存中读取数据; |