强缓存与协商缓存
当我们第一次访问一个网址时,服务器会返回所有资源,但是当我们第二次访问时是没有必要让浏览器给我们再次返回所有资源的,我们可以不去访问服务器而是直接从内存(from memory cache) 或 硬盘(from dist cache) 中读取第一次访问时存下来的对应的副本,这个存下来的动作就是缓存(动词),存下来的这些副本也是缓存(名词)。
为什么需要缓存?
客观因素
- 网络请求与加载相比较于cpu的计算要慢很多
- 网络请求的不稳定性(受环境因素影响大
缓存的优点
- 减少了不必要的数据访问,节省带宽
- 节省了服务器的负担,提高了网站的性能
- 加快了浏览器加载资源以及页面的速度
哪些资源可以被缓存?
- 主要为静态资源如:
- js
- css
- img
强缓存
强缓存也就是强制缓存,在浏览器初次请求时,服务器会判断返回的资源是否能被缓存,从而在response header中返回缓存对应的配置字段cache-control/expires告知浏览器去进行相应的操作,其中:
-
expires
格式: expires: Fri, 18 June 2021 01:03:05 GMT
http1.0时代定义的字段,表示过期时间,在这个时间之前,如需要,客户端将直接从缓存再次获取资源而非访问服务器。
-
cache-control
http1.1时代定义的字段,相比于expires有更多可以设置的值,比如:
-
cache-control: max-age=2592000,public
max-age后面表示时间,单位为秒,上面表示在30天的有效时间内,通过读取缓存来获取该资源
public 表示客户端以及服务端都可以缓存该资源
-
-
cache-control: max-age=xxx private
表示在xxx秒的有效时间内,通过读取缓存来获取该资源
private 表示只有客户端可以缓存该资源
-
cache-control: no-cache
跳过强制缓存(不妨碍协商缓存),每次请求的时候都访问服务器
-
cache-control: no-store
不缓存,既不进行强缓存,也不进行协商缓存
ps:
- 现在的浏览器可以兼容expires与cache-control共存,当两者共同出现的时候浏览器将以cache-control为主
- 强缓存中资源返回的status为200
协商缓存
协商缓存也叫对比缓存,是服务端的一种缓存策略,也就是由服务器通过资源标识对比服务端资源与客户端资源是否一样来判断资源能否继续使用缓存。
-
当客户端初次请求服务器时,服务器会返回资源以及资源标识etag/last-modified
-
当客户端再次请求时,会携带上相应的资源标识去访问服务器,服务器对比判断资源一致,则返回状态304,客户端继续使用缓存,否则返回状态200与最新的资源内容以及新的etag/last-modified
资源标识
服务器在Response Header中返回的资源标识有两种,而客户端在请求中的Request Header携带的相应的也有两种:
-
last-modified
格式:last-modified: Thu, 17 June 2021 09:49:49 GMT
-
资源的(上次)最后修改时间
-
初次请求时服务器返回资源与last-modified,再次请求时,客户端会在Request Header中携带if-modified-since字段去访问服务器,该字段的值与last-modified的值一致
-
服务器接收到if-modified-since,会判断服务器中对应的资源的最后修改时间是否与传过来的值一致,一致则返回304,否则则返回200,以及最新的资源与最新的资源修改时间last-modified
-
-
etag
格式:etag: '60b9d61e-9e8b8'
-
资源的唯一标识,根据资源内容生成(字符串,每个文件唯一,类似文件打包生成的hash)
-
初次请求时服务器返回资源与etag,再次请求时,客户端会在Request Header中携带if-none-match字段去访问服务器,该字段的值与etag的值一致
-
如果资源没有发生变化,则服务器针对相应的资源算出来的etag的值不变,返回304,如果发生变化,则返回200与最新的资源与最新的etag
-
借用一张对比图,可以更加直观地看到直接请求资源与协商后304状态下返回的size的大小:
ps:
- etag 与 last-modified 可以共存,两者并不冲突
- 两者共存时会优先使用etag,因为last-modified只能精确到秒级
- 如果资源被重复生成,但是内容不变,last-modified的值会变化,但是etag不变,所以etag更加精准
刷新操作对缓存的影响
普通刷新
指通过在地址栏输入url,前进后退等
- 强制缓存与协商缓存都有效
手动刷新
windows: F5,mac: cmd + r、点击刷新按钮、右键菜单刷新等
- 强制缓存失效,协商缓存有效
强制更新
windows: ctrl + F5,mac: shift + cmd + r 等操作
- 强制缓存,协商缓存失效
总结
借用一张流程图对强缓存与协商缓存做一个总结:
参考资料
- 主要参考了慕课网 双越老师关于缓存相关的视频资料