浏览器缓存:强缓存和协商缓存

172 阅读4分钟

缓存判断:

浏览器会判断所请求的资源是否在缓存里,如果请求的资源在缓存里并且没有失效,那么就直接使用,否则向服务器发起新的请求。

下面就缓存展开详细说一下:

浏览器缓存:

浏览器将用户请求过的静态资源(html、css、js),存储到电脑本地磁盘中,当浏览器再次访问时,就可以直接从本地加载,不需要再去服务端请求了。

缓存优点

减少了冗余的数据传输,节省网费;
减少服务器的负担,提升网站性能
加快了客户端加载网页的速度

缓存缺点

如果处理不当,可能会导致服务端代码更新了,但是用户缺还是老页面。

缓存流程

浏览器里有一个专门存放缓存规则的数据库,也可以说是映射表,把缓存资源信息,同电脑磁盘中的实际文件的地址,对应起来。

avatar

缓存规则是在response header中携带

缓存规则:强缓存和协商缓存

强缓存

如果资源没过期,就取缓存,如果过期了,则请求服务器。

如何判断资源是否过期,也就是说强缓存的规则怎么看?
主要看response header中的cache-control的值(expires基本已经淘汰了),cache-control取值含义:
private: 仅浏览器可以缓存
public: 浏览器和代理服务器都可以缓存(对于privatepublic,前端可以认为一样,不用深究)
max-age=xxx 过期时间(重要)
no-cache 不进行强缓存(重要)
注意:规则可以同时多个

所以,对于强缓存,我们主要研究 Cache-Control 中的 max-age 和 no-cache

所以,判断该资源是否命中强缓存,就看 response 中 Cache-Control 的值,如果有max-age=xxx秒,则命中强缓存。如果Cache-Control的值是no-cache,说明没命中强缓存,走协商缓存。

avatar

avatar

所以强缓存步骤已经很清晰了:

第一次请求 a.js ,缓存表中没该信息,直接请求后端服务器。
后端服务器返回了 a.js ,且 http response header 中 cache-control 为 max-age=xxxx,所以是强缓存规则,存入缓存表中。
第二次请求 a.js ,缓存表中是 max-age, 那么命中强缓存,然后判断是否过期,如果没过期,直接读缓存的a.js,如果过期了,则执行协商缓存的步骤了。
注意

这里有个问题,就是 max-age = 0 ,和 no-cache 有啥区别,我理解的是,no-cache直接不进行强缓存,让你去走协商缓存,而max-age=0是进行强缓存,但是过期了,需要更新。。。虽然实际上看起来两者效果是一样的。

协商缓存

触发条件:

Cache-Control 的值为 no-cache (不强缓存)
或者 max-age 过期了 (强缓存,但总有过期的时候)
也就是说,不管怎样,都可能最后要进行协商缓存(no-store除外)

avatar
这个图,虽然强缓存命中,但是也有 ETag 和 Last-Modified ,这两个就是协商缓存的相关规则。虽然之前的强缓存流程和他俩没关。。。

ETag:每个文件有一个,改动文件了就变了,可以看似md5

Last-Modified:文件的修改时间

也就是说,每次http返回来 response header 中的 ETag和 Last-Modified,在下次请求时在 request header 就把这两个带上(但是名字变了ETag-->If-None-Match,Last-Modified-->If-Modified-Since ),服务端把你带过来的标识,资源目前的标识,进行对比,然后判断资源是否更改了。

这个过程是循环往复的,即缓存表在每次请求成功后都会更新规则。

avatar
avatar
所以协商缓存步骤总结:

请求资源时,把用户本地该资源的 ETag 同时带到服务端,服务端和最新资源做对比。
如果资源没更改,返回304,浏览器读取本地缓存。
如果资源有更改,返回200,返回最新的资源。

缓存命中显示

1、从服务器获取新的资源
avatar

2、命中强缓存,且资源没过期,直接读取本地缓存
avatar

3、命中协商缓存,且资源未更改,读取本地缓存
avatar

注意:协商缓存无论如果,都要向服务端发请求的,只不过,资源未更改时,返回的只是header信息,所以size很小;而资源有更改时,还要返回body数据,所以size会大。

强缓存和协商缓存的区别:

相同点:都是从浏览器端读取资源。

不同点:

1、强缓存不发请求给服务器。

2、协商缓存发请求给服务器,根据服务器返回的信息决定是否使用缓存。