http缓存
# 写在前面
http 缓存,通过复用缓存资源,加快资源获取速度,减少了客户端等待时间和网络流量,同时也能缓解服务器端的压力,提高用户体验,提升网站性能。
# 缓存分类
强缓存:强制使用缓存
协商缓存:和服务器协商确认这个缓存能不能用
# 强缓存
不需要发送请求到服务端,直接读浏览器本地缓存,在 network 中显示的 HTTP 状态码是 200,在 chrome 中,强缓存又分为 Disk Cache(存放在硬盘中,一般存储费脚本资源,如 css)和 Memory Cache(存放在内存中, 一般存储的有字体、图片、脚本),存放位置由浏览器控制。
是否强缓存是由 Expires、Cache-Control 和 Prama 三个 Header 属性共同控制。
Expires 规则:是一个日期,浏览器发起请求时,会根据系统时间和 Expires 的值进行比较。如果系统时间超过该值,则缓存失效。 问题:当系统时间和服务器时间不一致,会有缓存期不准的可能。 优先级: 最低。
Cache-Control 常见的属性值
- max-age: 单位是秒,缓存时间计算的方式是距离发起请求的秒数,超过这个秒数则缓存失败
- no-cache:不使用强缓存
- no-store:禁止使用缓存(包括协商缓存)
- private: 专用于个人缓存,中间代理、cdn 等不能缓存此相映
- public:响应可以被中间代理、cdn 等缓存
- must-revalidate:在缓存过期前可以使用,过期后必须向服务器验证
优先级:比 Expires 高
Pragama 规则:只能设置 no-cache,不使用强缓存 优先级:最高
# 协商缓存
协商缓存会先向服务器发送一个请求,服务器会根据这个请求头中是否设置了 If-Modified-Since 或者 If-None-Match 的时候命中协商缓存,如果命中,则返回 304 状态码,并且响应头会设置 Last-Modified 或者 ETag 属性, 通知浏览器从缓存中读取资源。
- ETag/If-None-Match【优先级较高】
属性值是一串 hash 码,代表资源的标识符,当服务端的文件变化时候,hash 码会随之改变,通过请求头中的 If-None-Match 和当前文件的 hash 值进行比较,如果相等则命中协商缓存。ETag 又有强弱校验之分,如果 hash 码以'W/'开头的一串字符串,说明此时协商缓存是弱校验,只有服务器上的文件差异(根据 ETag 计算方式来决定)达到触发 hash 值后缀变化的时候,才会真正请求资源,否则返回 304 并加载浏览器缓存。
- Last-Modified/If-Modified-Since【性能优】 属性值是日期时间,代表的是文件的最后修改时间,第一次请求服务端会把资源的最后修改时间放到 Last-Modified 响应头中,第二次发起请求的时候,请求头上会带上上一次的 Last-Modified 的时间,并放到 If-Modified-Since 请求头属性中,服务端根据文件最后一次修改时间和 If-Modified-Since 的值进行比较,如果相等,返回 304,并加载浏览器缓存。
# 总结
图片、不常变化的 js 等静态资源使用缓存来提高页面加载速度。
# 用户行为都浏览器缓存的控制
- 地址栏访问 正常用户行为,触发正常的浏览器缓存机制。
- F5 刷新 浏览器会设置 max-age 为 0,跳过强制缓存,进行协商缓存判断
- ctrl+F5 强制刷新: 跳过强缓存和协商缓存,直接从服务器拉取资源。