本文目录:1、引入html
2、CDN定义前端
3、关于缓存webpack
4、浏览器缓存web
客户端直接从源站点获取数据,当服务器访问量大时会影响访问速度,进而影响用户体验,且没法保证客户端与源站点间的距离足够短,适合传输数据。ajax
CDN解决的正是如何将数据快速可靠地从源站点传递到客户端,经过CDN对数据的分发,用户能够从一个距离较近的服务器获取数据,而不是源站点,从而达到快速访问、且能减小源站点负载压力的目的。算法
CDN:Content Delivery Network/Content Ddistribute Network,即内容分发网络chrome
客户端访问网站的过程:gulp
一、用户在浏览器访问栏中输入要访问的域名;浏览器
二、浏览器向DNS服务器请求对该域名的解析;缓存
三、DNS服务器返回该域名的IP地址给浏览器
四、浏览器使用该IP地址向服务器请求内容。
五、服务器将用户请求的内容返回给浏览器。
一、用户在浏览器中输入要访问的域名。
二、浏览器向DNS服务器请求对域名进行解析。因为CDN对域名解析进行了调整,DNS服务器会最终将域名的解析权交给CNAME指向的CDN专用DNS服务器。
三、CDN的DNS服务器将CDN的负载均衡设备IP地址返回给用户。
四、用户向CDN的负载均衡设备发起内容URL访问请求。
五、CDN负载均衡设备会为用户选择一台合适的缓存服务器提供服务。
选择的依据包括:根据用户IP地址,判断哪一台服务器距离用户最近;根据用户所请求的URL中携带的内容名称,判断哪一台服务器上有用户所需内容;查询各个服务器的负载状况,判断哪一台服务器的负载较小。
基于以上这些依据的综合分析以后,负载均衡设置会把缓存服务器的IP地址返回给用户。
六、用户向缓存服务器发出请求。
七、缓存服务器响应用户请求,将用户所需内容传送到用户。
若是这台缓存服务器上并无用户想要的内容,而负载均衡设备依然将它分配给了用户,那么这台服务器就要向它的上一级缓存服务器请求内容,直至追溯到网站的源服务器将内容拉取到本地。
没有CDN:浏览器缓存
使用了CDN:浏览器缓存+CDN缓存
在用户第一次访问网站后,网站的一些静态资源如图片等就会被下载到本地,做为缓存,当用户第二次访问该网站的时候,浏览器就会从缓存中加载资源,不用向服务器请求资源,从而提升了网站的访问速度,而若使用了CDN,当浏览器本地缓存的资源过时以后,浏览器不是直接向源站点请求资源,而是向CDN边缘节点请求资源,CDN边缘节点中也存在缓存,若CDN中的缓存也过时,那就由CDN边缘节点向源站点发出回源请求来获取最新资源。
浏览器在加载资源时,先根据这个资源的一些http header判断它是否命中强缓存,若是命中,浏览器直接从本身的缓存中读取资源,不会发请求到服务器,当强缓存没有命中的时候,浏览器必定会发送一个请求到服务器,服务器端依据资源的另一些http header验证这个资源是否命中协商缓存,若是命中,服务器会将这个请求返回,可是不会返回这个资源的数据,而是告诉客户端能够直接从缓存中加载这个资源,因而浏览器仍是从本身的缓存中加载资源,当协商缓存也没有命中的时候,浏览器直接从服务器加载资源数据。
CDN节点缓存机制在不一样服务商中是不一样的,但通常都遵循HTTP协议,经过http响应头中的Cache-Control:max-age的字段来设置CDN节点文件缓存时间。当客户端向CDN节点请求数据时,CDN会判断缓存数据是否过时,若没有过时,则直接将缓存数据返回给客户端,不然就向源站点发出请求,从源站点拉取最新数据,更新本地缓存,并将最新数据返回给客户端。CDN服务商通常会提供基于文件后缀、目录多个维度来指定CDN缓存时间,为用户提供更精细化的缓存管理。CDN缓存时间会对“回源率”产生直接的影响,若CDN缓存时间短,则数据常常失效,致使频繁回源,增长了源站的负载,同时也增大了访问延时;若缓存时间长,数据更新时间慢,所以须要针对不一样的业务需求来选择特定的数据缓存管理。
一、在地址栏中输入网址后按回车或者点击转到按钮
浏览器以最少的请求来获取网页的数据,浏览器会对全部没有过时的内容直接使用本地缓存即便用强缓存,从而减小了对服务器的请求,Expires、max-age标志只对这种方式有效。
二、按F5或浏览器刷新按钮
浏览器会在请求中附加比要的缓存协商,但不容许浏览器直接使用本地缓存即跳过强缓存的判断,直接进行协商缓存的判断,Last-Modified、ETag在这种方式发挥做用。
三、按Ctrl+F5或按Ctrl并点击刷新按钮
强制刷新,彻底不使用缓存
CDN节点对开发者时透明的,能够经过CDN服务商提供的“刷新缓存”接口来达到清理CDN节点缓存的效果,强制使数据过时,从而获取到最新的数据。
这一点主要解析浏览器缓存以及缓存机制的详细过程。
第三点说到强缓存与协商缓存,下面从这两点提及:
当浏览器对某个资源的请求命中了强缓存时,返回的http状态码为200,在chrome开发者工具中的network中的size会显示from cache
强缓存时利用Expires或者Cache-Control这两个http header实现的,都用来表示资源在客户端缓存的有效期
一、浏览器第一次跟服务器请求一个资源,服务器在返回这个资源的同时,在response的header加上Expires的header
二、浏览器在接收到这个资源后,会把这个资源连同全部的response header一块儿缓存下来,因此缓存命中的请求返回的header并非来自服务器,而是来自以前缓存的header
三、浏览器再请求这个资源时,先从缓存中寻找,找到这个资源后,拿出Expires跟当前的请求时间比较,若是请求时间在Expires指定的时间以前,就能命中缓存,不然就不行。
四、若是缓存没有命中,浏览器直接从服务器加载资源时,Expires Header在从新加载的时候会被更新
Expires是服务器返回的一个绝对时间,在服务器时间与客户端时间相差较大时,缓存管理容易出现问题,好比随意修改下客户端时间,就能影响缓存命中的结果,因此在http1.1的时候,提出了一个新的header,也就是Cache-Control,这是一个相对时间,在进行缓存命中的时候,都是利用客户端时间进行判断,所以更有效安全一些,在配置缓存的时候,以秒为单位,用数值表示:如:Cache-Control:max-age=315360000,它的缓存过程是:
一、浏览器第一次跟服务器请求一个资源,服务器在返回这个资源的同时,在response的header加上Cache-Control的header
二、浏览器在接收到这个资源的时候,会把这个资源连同全部response header一块儿缓存下来
三、浏览器再次请求这个资源的时候,先从缓存中寻找,找到这个资源以后,再拿这个过时时间跟当前的请求时间比较,若是请求时间在过时时间以前,就能命中缓存,不然就不行。
四、若是缓存没有命中,浏览器直接从服务器加载资源时,Cache-Control在从新加载的时候会被更新
这两个header能够只用一个,也能够同时用两个,同时存在时,Cache-Control优先级高于Expires
两种方式来设置是否启用强缓存:
一、经过代码的方式,在web服务器返回的响应中添加Expires和Cache-Control Header
二、经过配置web服务器的方式,让web服务器在响应资源的时候统一添加Expires和Cache-Control Header
强缓存是前端性能优化最有力的工具,对于有大量静态资源的网页,必定要利用强缓存,提升响应速度,一般是为这些静态资源所有配置一个超时时间超长的Expires或Cache-Control,这样用户只会在第一次访问网站时加载静态资源,其余时间只要缓存没有失效而且用户没有强制刷新的条件下都会从缓存中加载。
然而这种缓存配置方式会带来一个问题,就是当资源更新时,客户端因为有缓存不会向服务器请求最新的资源,这个问题已有解决方案:
经过更新页面中引用的资源路径,让浏览器主动放弃缓存,加载新资源。
但要实现有更新的文件才须要浏览器从新加载,所以必须让url的修改与文件内容相关联,利用数据摘要算法对文件求摘要信息,摘要信息与文件内容一一对应,这一点许多前端构建工具都作到了,如webpack
解决方法:
一、ctrl+F5
二、浏览器隐私模式开发
三、chrome开发者工具里将Disable cache选项打勾,阻止缓存
四、在开发阶段,给资源加上一个动态的参数,因为每次资源的修改都要更新引用的位置,同时修改参数的值,因此操做起来不是很方便,除非是在动态页面好比jsp里开发就能够用服务器变量来解决,或者用前端构建工具来处理这个参数修改的问题。
五、若是资源引用的页面被嵌入到了一个iframe里面,能够在iframe的区域右键从新加载该页面
六、若是缓存问题出如今ajax请求中,最有效的解决办法就是ajax的请求地址追加随机数
七、动态设置iframe的src时,有可能由于缓存问题致使看不到最新效果,在src后面添加随机数便可
八、经过前端开发工具grunt gulp等的插件来启动一个静态服务器,则在这个服务器下全部资源返回的response header中,Cache-Control始终被设置为不缓存
发布问题:若页面和它引用的资源路径同时更新了,不论是先部署页面仍是先部署资源都会带来各类问题,这是因为资源是覆盖式发布的,即用待发布资源覆盖已发布资源。
解决办法就是实现非覆盖式发布:把有修改的资源文件做为一个新的文件发布,不对已有的资源文件进行覆盖,这样用户还能够请求旧的资源文件,不至于发生页面错乱的问题,这样先部署静态资源,再覆盖式部署页面,等到用户访问新页面的时候,新的资源文件也已发布,就能够正确请求,便可解决问题。
若是命中协商缓存,请求响应返回的http状态为304以及一个Not Modified字符串,协商缓存利用的是【Last-Modified、If-Modified-Since】、【ETag、If-None-Match】这两对header来管理的。
【Last-Modified、If-Modified-Since】:
一、浏览器第一次跟服务器请求一个资源,服务器在返回这个资源时,在response的header加上Last-Modified的header,表示这个资源在服务器上的最后修改时间
二、浏览器再次向服务器请求这个资源时,在request的header加上If-Modified-Since的header,这个header的值就是上一次请求时返回的Last-Modified的值
三、服务器再次收到资源请求时,根据浏览器传过来If-Modified-Since和资源在服务器上的最后修改时间判断资源是否有变化,若是没有变化则返回304 Not Modified,可是不会返回资源内容,若是有变化就返回资源内容,当服务器返回304 Not Modified的响应时,response header中不会再添加Last-Modified的header,由于资源没有变化,Last-Modified的值也不变
四、浏览器收到304的响应后,就会从缓存中加载资源
五、若是协商缓存没有命中,浏览器直接从服务器加载资源时,Last-Modofied header在从新加载的时候会被更新,下次请求时,If-Modified-Since会采用上一次返回的Last-Modified的值
这一对header都是根据服务器时间返回的,有时候会有服务器资源有变化,但最后修改时间却没有变化的状况,所以有了
【Etag、If-None-Match】:
一、浏览器第一次向服务器请求一个资源,服务器在返回这个资源的同时,在response的header加上ETag的header,这个header是服务器根据当前请求的资源生成的一个惟一标识,是一个字符串,只要资源内容发生改变,这个字符串也会改变,跟时间没有关系
二、浏览器再次请求这个资源的时候,在request的header上加上If-None-Match的header。这个header的值是上一次请求返回的ETag的值
三、服务器再次收到资源请求时,根据客户端传过来的If-None-Match和从新生成的该资源的新的ETag作比较,相同则返回304 Not Modified,不会返回资源内容,若是不一样则返回资源内容,但这里即便资源没有发生变化,也会返回ETag,由于这个ETag从新生成过,即便没有ETag没有变化
四、浏览器收到304响应后,就从缓存中加载资源
通常服务器上的【Last-Modified、If-Modified-Since】和【Etag、If-None-Match】会同时启用,协商缓存须要配合强缓存使用
参考文章:
http://www.javashuo.com/article/p-tfhkkfir-ex.html
http://www.javashuo.com/article/p-sqrtakmh-gh.html
https://www.zhihu.com/question/20790576
http://www.cnblogs.com/lyzg/p/5125934.html