彻底理解web缓存

1.  web缓存(百科)

         web缓存HTTP缓存) ,是用于临时存储(缓存)web文档(html页面、图形等),以减少服务器延迟的一种信息技术。web缓存会保存web文档的副本,如果满足某些条件,则可以通过缓存满足后续请求。

        优点:减轻服务器压力,减少数据传输,节省网络带宽和浏览,缩短页面加载时间,提升用户体验。

2.  缓存分类

        从缓存服务于单一用户和多个用户角度来看,可以分为:

        私有缓存:针对专有用户,web浏览器中内建的私有缓存,在本地电脑的磁盘和内存中设置缓存文件夹存放缓存内容。如chrome浏览器的缓存位置放在 C:\Users\Your_Account\AppData\Local\Google\Chrome\User Data\Default中的cache文件夹和media文件夹。

        公有缓存:有代理服务器缓存、CDN缓存等。共享代理服务器、或者是缓存代理服务器、或者代理缓存。基本思想是:在靠近客户单的地方使用小型缓存服务器,更高层次中,逐级采用更大、功能更强的缓存服务器装载更多用户共享的资源。见下图

        上图中的缓存处理流程,见下图

        从前端考虑,上图可以缩略为

        CDN(内容分发网络),广泛采用各种缓存服务器,将这些缓存服务器分布到用户访问相对集中的地区或网络中,在用户访问网站时,利用全局负载均衡技术将用户的访问指向距离最近的工作正常的缓存服务器上,由缓存服务器直接响应用户请求。

        CDN缓存详细的原理图,如下:

clipboard.png

 

3.  浏览器缓存机制

        web前端开发人员,主要是从浏览器角度来理解和设置web缓存的。所以总结梳理一下浏览器缓存机制。

        浏览器缓存分为强缓存和协商缓存:强缓存,浏览器加载资源时,先根据http header中的信息(在http1.0中,通过Expires实现,时间精确到秒,如果服务器在1秒内修改内容,不太合适;在http1.1中,通过Cache-Control响应头来实现,现在主流使用http1.1)判断是否命中强制缓存,如果命中,浏览器直接从自己的缓存中读取资源,不会发请求到服务器。协商缓存,当强制缓存没有命中时,浏览器会向服务器发送请求,服务器端通过http header中的另外一些设置验证请求资源是否命中协商缓存,如果命中协商缓存,服务器会将这个请求返回304,不返回这个资源信息,告诉客户端可以直接从缓存中加载这个资源,然后浏览器从自己的缓存中加载这个资源;如果未命中缓存,服务器将资源返回给客户端,返回状态码200,并更新本地缓存数据 。强缓存和协商缓存的区别:强缓存不发请求到服务器,协商缓存会发请求到服务器。

1.  缓存规则解析

        在客户端第一次请求数据时,此时缓存数据库中没有对应的缓存数据,需要请求服务器,服务器返回数据和缓存规则后,将数据和缓存规则存储至缓存数据库中。

       

2. 强制缓存

        已经存在缓存数据时,即上述第1.执行过后,强制缓存图解如下:

3.  协商缓存

        已经存在缓存数据时,即上述第1.执行过后,协商缓存图解如下:

        强制缓存和协商缓存可以同时存在,强制缓存优先级高于协商缓存。

4.  如何设置缓存

4.1  html meta设置

        html meta 标签控制缓存,不是http协议。

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="pragma" content="no-cache">
	<title>Leet Code</title>
</head>
<body>
</body>
</html>

<meta http-equiv="pragma" content="no-cache"> 告诉浏览器当前页面不被缓存,每次访问都需要去服务器获取。该方法只有部分流量可以支持,所有缓存代理服务器都不支持,代理服务器不解析html内容

4.2  http头信息设置缓存

        http头部信息设置缓存,通过Expires(强缓存)、Cache-control(强缓存)、Last-Modified/if-Modified-Since(协商缓存)、Etag/if-None-Match(协商缓存)实现

     1.  Expires

        http1.0 提出的表示资源过期的配置,描述的是一个精确到秒的绝对时间,由服务器返回,用GMT格式的字符串表示,如  expires:Thu, 17 Dec 2020 09:42:46 GMT。

       读取缓存数据条件:缓存过期时间(服务器的)< 当前时间(客户端的)

        缺点:如果服务器和客户端时钟不同步,跨时区,时间误差就很大。所以,从http1.1版本开始,使用 cache-control:max-age=多少秒 替代

     2.  Cache-control

       描述的是一个相对时间,在进行缓存命中时,利用客户端时间进行判断。

        读取缓存数据条件:上次缓存时间(客户端的)+ max-age < 当前时间(客户端的)

        cache-control其他值详解:

        public:客户端和代理服务器都可以缓存

       private:客户端可以缓存,默认

       max-age = xxx :缓存内容将在 xxx秒后失效

       no-cache:需要使用对比缓存来验证缓存数据

       no-store:所有内容都不会缓存,强制缓存

       expires和cache-control可以同时配置,在response header中,cache-control高于expires

     3.  Last-Modified/if-Modified-Since

      配合cache-control使用。Last-Modified:表示请求资源的最后修改时间,由服务器返回给浏览器;if-Modified-Since:当强缓存失效,发现资源有 last-modified声明,则再次向服务器请求时带上头 if-modefied-since,表示请求时间。服务器收到请求后发现有 if-modified-since,则与被请求资源的最后修改时间比较,如果最后修改时间较新,说明资源又被改动过,则返回数据资源,status:200;如果最后修改时间较旧,说明资源无修改,则返回status:304,不返回数据资源,告知浏览器继续在浏览器cache中请求使用。

       缺点:last-modified标注的最后修改时间精确到秒,如果资源在1秒内多次修改,它不能标注文件的准确修改时间;如果某些文件被定期生成,内容没有发生任何变化,但是last-modified却修改了,导致文件不能使用缓存;也可能存在服务器时间没有准确获取文件修改时间,或者与代理服务器时间不一致等情形,导致不能使用缓存。

        http1.1中 Etag解决了上面的问题。

      4.  Etag/if-none-match

     配合cache-control使用。Etag:web服务器请求资源时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定)。Apache中,Etag值,默认是将文件的索引节(INode)、大小(Size)和最后修改时间(MTime)进行hash后得到。If-none-match:当缓存资源过期时(通过cache-control的max-age判断),如果资源有etag声明,则再次向服务器请求时,带上header信息 if-none-match(etag的值)。服务区收到请求后,发现有 if-none-match,则与被请求资源的相应校验串进行比对,如果不同,说明资源又被改动过,则将请求资源返回,返回状态码200;相同,说明资源无修改,则返回status 304,告知浏览器从浏览器cache中获取资源信息。

5.  实际综合

        对于强制缓存,服务器通知浏览器一个缓存时间,下次请求,如果在缓存时间内,则执行协商缓存策略;对于协商缓存,将缓存信息中的etag和last-modified通过请求发送给服务器,由服务器校验判断,是返回304,浏览器在浏览器缓存中读取资源,还是服务器返回给客户端数据资源。

       

引用:

1. 百度百科:CDN https://baike.baidu.com/item/CDN/420951?fr=aladdin

2. 十分全面!作为前端应当了解的那些Web缓存知识 https://www.toutiao.com/i6287820101760582145/?timestamp=1608189232&app=news_article_lite&group_id=6287817483648008449&use_new_style=1&req_id=202012171513520101300361523B015FD3

3. 详解web缓存 https://segmentfault.com/a/1190000006741200https://segmentfault.com/a/1190000006741200https://segmentfault.com/a/1190000006741200


版权声明:本文为songlf521原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。