浏览器缓存机制
2019-03-04 本文已影响0人
一包
参考原文:https://www.cnblogs.com/shixiaomiao1122/p/7591556.html
https://www.jianshu.com/p/1a1536ab01f1
浏览器缓存主要有两类:协商缓存和强缓存
- 浏览器加载资源时会根据一些资源的http头,判断是否命中强缓存,如果命中,返回200,浏览器就从缓存中加载资源;
- 如果没有命中强缓存,浏览器会发送请求到服务器,服务器根据资源的另一些http 头验证是否命中协商缓存,如果命中,返回304并带上新的response header通知浏览器从缓存中读取资源
- 当协商缓存没有命中的时候,浏览器直接从服务器加载资源数据
两者的共同点是,都是从客户端缓存中读取资源;区别是强缓存不会发请求,协商缓存会发请求。
强缓存
强缓存:不会向服务器发送请求,直接送缓存中读取资源。返回状态码:200。
缓存中header的参数
- Expires(HTTP 1.0): 表明过期时间。浏览器再次加载资源,如果在这个过期时间内,则命中强缓存。
- Cache-Control(HTTP 1.1):是 expires 的补充。使用的是相对时间的概念。常用属性如下:
- max-age: 设置缓存的最大的有效时间,单位为秒(s)。max-age会覆盖掉Expires
- s-maxage: 只用于共享缓存,比如CDN缓存(s -> share)。与max-age 的区别是:max-age用于普通缓存,
而s-maxage用于代理缓存。如果存在s-maxage,则会覆盖max-age 和 Expires.
所以判断缓存是否过期步骤是:
- 查看是否有cache-control 的max-age / s-maxage , 如果有,则用服务器时间date值 + max-age/s-maxage 的秒数计算出新的过期时间,将当前时间与过期时间进行比较,判断是否过期
- 查看是否有cache-control 的max-age / s-maxage,没有则用expires 作为过期时间比较
强缓存
-
强缓存是前端性能优化最有利的工具。对于有大量今天资源的网站,一定要利用强缓存,提高响应速度。
-
通常做法:将静态资源全部配置一个超时时间超长的Expires或Cache-Control。
协商缓存
协商缓存: 向服务器端发送请求,服务器根据请求的if-None-Match和if-Modified-Since判断是否命中协商缓存,如果命中,返回状态码304并带上新的response header通知浏览器从缓存中读取资源。
-
Last-Modify/If-Modify-Since:浏览器第一次请求一个资源的时候,服务器返回的header中会加上Last-Modify,Last-modify是一个时间标识该资源的最后修改时间;当浏览器再次请求该资源时,request的请求头中会包含If-Modify-Since,该值为缓存之前返回的Last-Modify。服务器收到If-Modify-Since后,根据资源的最后修改时间判断是否命中缓存。
-** Etag**:web服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定)。 - If-None-Match:当资源过期时(使用Cache-Control标识的max-age),发现资源具有Etage声明,则再次向web服务器请求时带上头If-None-Match (Etag的值)。web服务器收到请求后发现有头If-None-Match 则与被请求资源的相应校验串进行比对,决定是否命中协商缓存;
浏览器缓存过程
- 浏览器第一次加载资源,服务器返回200,浏览器将资源文件从服务器上请求下载下来,并把response header及该请求的返回时间一并缓存;
- 下一次加载资源时,先比较当前时间和上一次返回200时的时间差,如果没有超过cache-control设置的max-age,则没有过期,命中强缓存,不发请求直接从本地缓存读取该文件(如果浏览器不支持HTTP1.1,则用expires判断是否过期);如果时间过期,则向服务器发送header带有If-None-Match和If-Modified-Since的请求
- 服务器收到请求后,优先根据Etag的值判断被请求的文件有没有做修改,Etag值一致则没有修改,命中协商缓存,返回304;如果不一致则有改动,直接返回新的资源文件带上新的Etag值并返回200;;
- 如果服务器收到的请求没有Etag值,则将If-Modified-Since和被请求文件的最后修改时间做比对,一致则命中协商缓存,返回304;不一致则返回新的last-modified和文件并返回200;;