http强缓存和协商缓存
合理使用http缓存是前端性能优化的手段之一,是作为前端开发需要掌握的重要知识点。它可以加快我们获取资源的速度,减少网络传输,提升用户体验。
http缓存流程图如下:
http强缓存
浏览器直接读取本地缓存而不去请求服务器,我们在 Chrome 浏览器控制台Network面板中看到的 http Status 为 200 , Size 显示为 Disk Cache 或 Memory Cache 即表示当前资源走的是本地缓存,没有向服务器发送请求。
在Chrome中强缓存又分为 Disk Cache 和 Memory Cache,由浏览器控制存放位置,至于具体规则目前没有统一的说法。
http如何判断是否走强缓存呢?
强缓存由 Expires、Cache-Control 和 Pragma 3个 Header 属性共同来控制。
① Expires
http/1.0 的产物,指定缓存过期的事件,是服务器具体的时间点,但是他有个缺点,受本地时间影响,修改了本地时间可能会造成缓存失效。
Expires 现阶段主要用在一些不兼容 http/1.1的环境,如果在 Cache-Control 响应头设置了 max-age 或者 s-max-age 指令,那么 Expires 头会被忽略。
② Cache-Control
Cache-Control 是 http/1.1 中的重要缓存规则可以使用多种指令:
③ Pragma
Pragma 是 HTTP/1.0 中定义的一个header属性, 只有一个 no-cache 属性值,效果和 Cache-Control 中的 no-cache 一致,不使用强缓存,但是 HTTP 的响应头没有明确定义这个属性,所以它不能拿来完全替代 HTTP/1.1 中定义的 Cache-control 头。通常定义 Pragma 以向后兼容基于HTTP/1.0的客户端。。
http协商缓存
协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用浏览器缓存的过程。
协商缓存通过设置 Last-Modified 和 ETag 两种请求头来实现。
① ETag 和 If-None-Match
ETag 是服务器响应请求时,返回由服务器生成的当前资源文件的唯一标识,只要资源有变化,ETag 就会重新生成,首次请求资源时有服务器返回。
在下一次请求资源时会将上一次返回的 ETag 放到请求头的 If-None-Match 里,服务器对比 If-None-Match 里传来的 ETag 值与服务器的是否一致,以此判断是否资资源被修改过,如果修改了则返回新的资源文件和新的 ETag,若未修改则继续判断Last-Modified。
② Last-Modified 和 If-Modified-Since
在首次访问资源时,服务器返回资源 和 Last-Modified,Last-Modified 的值是这个资源在服务器上的最后修改时间,浏览器接收后缓存文件和 Last-Modified。
下次请求这个资源,浏览器检测到有 Last-Modified 这个 header ,于是添加If-Modified-Since这个 header 到请求头中,值就是Last-Modified中的值;
服务器去判断 If-Modified-Since 中的值与服务器中这个资源的最后修改时间是否一致,如果一致则返回 304 告诉浏览器可以使用缓存资源,不一致则返回 Status 200 个新的资源。
③ ETag 和 Last-Modified对比
1️⃣ Last-Modified 的时间只能精确到秒,一秒内修改多次的话从时间体现不出来变化,,ETag 精确度更高,每次改变都会重新生成。如果是负载均衡的服务器,各个服务器生成的Last-Modified也有可能不一致。
2️⃣ 在性能上,ETag 要逊于Last-Modified,毕竟 Last-Modified 只需要记录时间,而 ETag 需要服务器通过算法来计算出一个hash值。
3️⃣ 服务器校验优先考虑 ETag。