关于Web缓存的知识点总结
因为才写了关于响应式瀑布流懒加载的插件,做了简单的优化,但是发现,实用性并不强,不过对于其中过程中所涉及的东西能有一个更全面的认识,这里对于图片压缩等方面暂时不提,只说一说关于Web缓存方面的东西,这对于线上加载图片类资源还是很有用的(本人是准大三,很多地方总结的可能不到位,烦请指正,共勉)
-
什么是Web缓存?
通俗点讲,它就是一个存在于客户端和服务器之间的一个副本,当你第一次发出请求后,缓存根据请求保存输出内容的副本;之后当你再次发出相同的请求的时候(也就是URL相同,可以联想我们平时用ajax期间,为了防止读取缓存数据,给其请求的URL链接后附加Date或者随机数),缓存机制将决定是直接使用副本响应访问请求还是将请求发给服务器,这里也会涉及到计算机网络中的知识,包括304状态码等等,而这里面的原理将在后边提及。
-
Web缓存有什么用?
无论是学习期间还是工作面试,都少不了此类问题,关于Web缓存的理解,首先应该明白它有什么实际的作用,更能让我们对它有一个全面的认识。
1.减少不必要的请求发送,降低网络带宽消耗,这个就很好理解了,这里就不再赘述了。
2.降低服务器压力,减少对源服务器的请求。
3.降低网络延迟,加快页面打开速度(直接读取浏览器的缓存数据)。 Web缓存的类型有哪些?
-
1.数据库数据缓存
这个我是深有体会,因为之前在做基于Node的个人网站期间(初期是跟着别人教程走,对这个问题没什么感觉,后期添加扩展功能时,就发现了一些不恰当 的地方),虽然数据量级不大,但是以小见大,拿收藏文章的扩展功能举例,这个需要查两个文档的数据,而收藏功能一开始做是直接查询当前数据库的用户收藏信息,取消收藏亦如此,显而易见,用户量大了之后,数据库将不堪重负,所以你的耳边才会出现redis、memcached等解决方案,当你真正遇到这些问题的时候,你就不会再问为什么需要使用它们了;言归正传,那么数据库缓存的原理其实和浏览器大同小异,就是对于同类数据,在不影响返回结果的前提下,尽量避免与数据库直接交互,采取缓存优先的原则,不仅提高响应效率,也降低了数据库负荷。
-
2.服务器端的缓存
这里必须要提到一个东西就是CDN,而CDN到底是一个什么原理呢?看图比较
原本的用户访问请求的处理是以下过程:
1.用户向浏览器提供要访问的域名;
2.浏览器调用域名解析函数库对域名进行解析,以得到此域名对应的IP地址;
3.浏览器使用所得到的IP地址,域名的服务主机发出数据访问请求;
4.浏览器根据域名主机返回的数据显示网页的内容。
但是在用了CDN之后,就发生了改变,因为对于CDN客户来说,不需要改动网站架构,只需要修改自己的DNS解析,设置一个CNAME指向CDN服务商即可。
其基本工作原理是下面这个样子:
1.用户向浏览器提供要访问的域名;
2.浏览器调用域名解析库对域名进行解析,由于CDN对域名解析过程进行了调整,所以解析函数库得到的是该域名对应的CNAME记录(由于现在已经是使用了CDN服务,CNAME为CDN服务商域名),为了得到实际IP地址,浏览器需要再次对获得的CNAME域名进行解析以得到实际的IP地址;在此过程中,使用的全局负载均衡DNS解析,如根据地理位置信息解析对应的IP地址,使得用户能就近访问。(CDN服务来提供最近的机器)
3.此次解析得到CDN缓存服务器的IP地址,浏览器在得到实际的IP地址以后,向缓存服务器发出访问请求;
4.缓存服务器根据浏览器提供的要访问的域名,通过Cache内部专用DNS解析得到此域名的实际IP地址,再由缓存服务器向此实际IP地址提交访问请求;
5.缓存服务器从实际IP地址得得到内容以后,一方面在本地进行保存,以备以后使用,二方面把获取的数据返回给客户端,完成数据服务过程;
6.客户端得到由缓存服务器返回的数据以后显示出来并完成整个浏览的数据请求过程。
3.浏览器端缓存
4.Web应用层缓存
3 和 4在后续会详细描述、
浏览器的缓存机制
缓存虽然好,但并不意味着所有的资源都应该采用缓存机制来存取,它是由一套完整的规则定义出的结果,来决定什么时候使用缓存中提供的副本提供服务,有的在HTTP协议有定义,有的则是由缓存的管理员设置。
而对于浏览器的缓存来讲,这里是从前端的视角来说明这些问题,缓存的规则是在HTTP协议头和HTML页面的meta标签中定义,它们分别从新鲜度和校验值两个方面来浏览器是应该选择读取缓存副本数据还是向源服务器发送请求。
1.新鲜度(过期机制)也就是缓存副本的有效期,一个缓存副本必须满足以下条件之后,浏览器才会认为它是有效的,分别是: “含有完整的国旗时间控制头信息”、“浏览器已经使用过这个缓存副本,并且在一个会话中已经检查过新鲜度”。
2.校验值(验证机制)是服务器返回资源的时候有时候会在控制头信息附带这个资源的Etag实体标签,用来作为浏览器再次请求过程的校验标识,如果不匹配,说明资源已经被修改或者过期,浏览器这个时候就会判定应该向源服务器请求资源,而不是读取缓存数据,这方面若要详细理解,还是得去看《计算机网络》和《HTTP权威指南》
3.对于浏览器的缓存控制方法比较多。
前端开发在HTML页面的控制可以看这个链接,对于如何在meta标签中设置一系列控制规则
而重点还是在对于HTTP的设置和理解上,而在HTTP请求和响应的消息报头中,常见的与缓存有关的消息报头如下:
-
关于HTTP中的设置规则:
Cache-Control 与 Expires: 这两个的作用一致,都是为了表明当前资源的有效期,提供给浏览器判断应该读取缓存还是向源服务器发送请求,只不过Cache-Control的可选择更多,设置更加细致罢了,并且,就算同时设置,其优先级高于Expires。
Last-Modified/Etag 与 Cache-Control/Expires: 配置Last-Modified/Expires的情况后,当浏览器再次访问同一个URL资源,即使这个资源的缓存存在,其还是会发送请求到服务器产讯文件是否已经修改过,如果没有,那么我们就会收到一个我们非常熟悉的东西,那就是304状态码,告知浏览器当前的状态,以判断后续应该执行的操作。但后者则不同,如果检测到本地的缓存还在有效时间范围内,浏览器将直接使用自己本地的缓存副本,不会发送任何请求,当两者共存时,后者的优先级高于前者,一般情况下,两者会搭配使用,因为即使服务器设置缓存时间,当用户点击刷新时,浏览器会忽略缓存继续向服务器发送请求,这个时候Last-Modified/Etag 将能够很好利用304,从而减少响应开销。
Last-Modified/ETag: 为什么使用Last-Modified已经足够让浏览器知道本地的缓存副本是否足够新,为什么还需要Etag呢?HTTP1.1中Etag的出现主要是为了解决几个Last-Modified的比较难解决的问题。
1.Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的新鲜度。
2.如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存。
3.有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形。
这里简单说一下: Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符,能够更加准确的控制缓存。Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。Etag的服务器生成规则和强弱Etag的相关内容可以参考。
这里得提一下一些具体操作对浏览器缓存的影响:
上面既然提到了缓存的一些具体设置,那么肯定也少不了了解“哪些请求不能被缓存?”
1.HTTP信息头中包含Cache-Control:no-cache,pragma:no-cache,或Cache-Control:max-age=0等告诉浏览器不用缓存的请求。
2.需要根据Cookie,认证信息等决定输入内容的动态请求是不能被缓存的。
3.经过HTTPS安全加密的请求。
4.POST请求无法被缓存。
5.HTTP响应头中不包含Last-Modified/Etag,也不包含Cache-Control/Expires的请求无法被缓存。
这里还没有更总结完,文字内容以 AlloyTeam为参考,结合其余知识点的汇总以及个人理解,还没更新完,待续。