前言对于每一个前端开发者来说,前端缓存都是不可避免的,那么前端缓存有哪些,又该如何设置呢?前端缓存只要分为HTTP缓存和浏览器缓存就可以了,我们单独介绍一下HTTP缓存。HTTP缓存分为两种:强缓存协商缓存。缓存是否仍然有效。顾名思义,协商缓存就是与服务器协商,最终决定是否使用本地缓存。强缓存当浏览器向服务器发起请求时,服务器会将缓存规则放入HTTP响应报文的HTTP头中,连同请求结果一起返回给浏览器。控制强制缓存的字段有Expires和Cache-Control,其中Cache-Control的优先级高于Expires。ExpiresExpires是HTTP/1.0控制网页缓存的一个字段。它的值是服务器返回请求的缓存结果时的过期时间。即再次发起请求时,如果客户端的时间小于Expires的值,则直接使用缓存的结果。到HTTP/1.1,Expire已经被Cache-Control取代。原因是Expires控制缓存的原理是比较客户端返回的时间和服务器返回的时间。如果由于某些原因导致客户端和服务器的时间不同(比如时区;客户端和服务器的时间不准确),那么强制缓存就会直接失效,强制缓存的存在也就没有意义了。当Cache-Control符合缓存策略时,服务端不会发送新的资源,但并不代表客户端和服务端没有对话,客户端还是会向服务端发送请求。除了在响应中使用,Cache-Control还可以在请求中使用。我们使用开发者工具模拟带有Cache-Control的请求:勾选Disablecache,刷新页面,可以看到RequestHeaders中有一个字段Cache-Control:no-cache。在HTTP/1.1中,Cache-Control是最重要的规则,主要用于控制网页缓存。主要的值是:public:所有的内容都会被缓存(客户端和代理服务器都可以缓存)public出现然后响应header,那么这个响应即使关联了HTTP验证也可以缓存,甚至响应状态通常无法缓存的代码代码。大多数情况下public不是必须的,因为显式的缓存信息(比如max-age)已经表明响应可以被缓存private:所有内容只能被客户端缓存,与Cache-Control的默认值相比,browse服务器可以缓存私有响应。但是,这些响应通常只为单个用户缓存,因此不允许中间缓存缓存它们。例如,用户的浏览器可以缓存包含用户隐私信息的HTML页面,但是CDN不能缓存no-cache:客户端缓存内容,但是是否使用缓存需要通过协商缓存来验证。no-cache的意思是你必须先和服务器确认返回的response是否发生了变化,然后你才能使用response来满足后续对约定url的请求。因此,如果存在合适的验证令牌(ETag),则no-cache启动往返以验证缓存的响应,但如果资源未更改,则避免下载no-store:不会缓存任何内容,即不使用强制缓存,也不使用协商cachingno-store是指直接禁止浏览器和所有中间缓存存储返回响应的任何版本,例如包含个人隐私数据或银行业务数据的响应。每次用户请求此资产时,都会向服务器发送请求并下载完整响应max-age=xxx(xxx为数字):缓存的内容将在xxx秒后过期document——从文档的第一代到文档不再新鲜不能使用的时间,协商缓存的最大合法生存期(以秒为单位)只是缓存过期,并不代表他和原来的serverarecurrentlyactivedocuments有一个真正的区别,它只是意味着是时候进行检查了,这被称为协商缓存,这意味着缓存需要询问原始服务器是否发生了某些变化,如果重新验证表明内容已经更改后,缓存会获取文档的新副本并将其存储在旧文档的位置,然后再将文档发送给客户端。如果重新验证的内容没有变化,缓存只需要获取新的header,包括新的有效期,更新缓存中的header,更新缓存中的header。使用条件方法重新检查HTTP。条件方法可以有效地实现重新验证。HTTP允许缓存向源服务器发送条件GET,请求服务器仅在文档与缓存中的现有副本不同时才发回对象主体。对于缓存,两个最有用的验证标头是If-Modified-Since::如果文档自指定日期以来已被修改,则执行请求的方法。它可以与Last-Modfied服务器响应标头结合使用。只有当修改的内容与缓存的版本不同时,才会获取内容。If-None-Match::服务器可以为文档提供特殊标签(ETag),而不是将其与最后修改日期匹配,这些标签的作用类似于序列号。如果缓存的标签和服务器文档中的标签不一样,If-None-Match头会执行请求的方法If-Modified-Since:/Last-Modified具体过程如下:客户端向服务器第一次使用时,服务器将最后修改日期(Last-Modified)附加到提供的文档中。再次请求资源时,如果没有命中强缓存,校验时会包含一个If-Modifed-Since头,其中包含Hasthedatethecachedcopywaslastmodified:If-Modified-Since:如果内容已被修改,服务器会发回一个带有200状态码和最新修改日期的新文档。如果内容没有被修改,它将返回304NotModified响应If-None-Match/ETag在某些情况下仅使用最后修改日期重新验证是不够的一些文档可能会定期重写(例如:从后台进程写入),但实际上包含的数据往往是相同的。虽然内容没变,但是修改日期会变。有些文件可能已经被修改,但修改的内容并不重要。无需重新加载世界各地缓存中的数据(例如填写评论)某些服务器无法准确确定其页面的最后修改日期某些服务器提供以毫秒为间隔更改的文档(例如,实时监视器),对于这些服务器来说,以一秒为粒度的修改日期可能是浏览器缓存不足当浏览器请求网站时,会加载各种资源,例如:HTML文档、图片、CSS和JS文件。对于一些不经常变化的内容,浏览器会将其保存在本地文件中,下次访问同一网站时直接加载这些资源,以加快访问速度。优点:减少页面加载时间;减少服务器负载;下面介绍几种具体的缓存方案:DNS缓存我们知道url其实只是一个别名,真正的服务器请求地址其实是一个IP地址。获取IP地址的方法是查询DNS映射表。虽然这是一个非常简单的查询,但每次用户访问一个url时都查询DNS会过于频繁。DNS会告诉你,不要经常来这里,如果我挂了,我们就玩不开心了。DNS查询过程耗时约20毫秒。在DNS查询过程中,浏览器什么都不做,一直空白。如果DNS查询很多,网页性能会受到很大影响,所以需要DNS缓存。不同浏览器的缓存机制不同:IE对DNS记录的默认缓存时间为30分钟,Firefox对DNS记录的默认缓存时间为1分钟,Chrome对DNS记录的默认缓存时间为1分钟。缓存时间长:减少重复的DNS查找,节省时间。缓存时间短:及时检测服务器IP变化,保证访问的正确性。CDN缓存CDN缓存是一种服务器端缓存。CDN服务商将源站资源缓存在遍布全国的高性能加速节点上。当用户访问相应的业务资源时,将用户调度到就近的节点。节点ip返回给用户。在web性能优化中,主要起到缓解源站压力,优化不同用户的访问速度和体验的作用。Process客户端访问网站的过程:无CDN:用户在浏览器访问栏输入要访问的域名;浏览器请求DNS服务器解析域名;DNS服务器将域名的IP地址返回给浏览器使用,该IP地址向服务器请求内容。服务器将用户请求的内容返回给浏览器。使用CDN:用户在浏览器中输入要访问的域名。浏览器请求DNS服务器解析域名。由于CDN调整了域名解析,DNS服务器最终会将域名解析权交给CNAME指向的CDN专用DNS服务器。CDN的DNS服务器将CDN的负载均衡设备的IP地址返回给用户。用户向CDN负载均衡设备发起内容URL访问请求。CDN负载均衡器会选择合适的缓存服务器为用户提供服务。选择的依据包括:根据用户的IP地址判断哪个服务器距离用户最近;根据用户请求的URL中携带的内容名称,判断哪个服务器有用户需要的内容;查询每台服务器的负载情况,判断哪台服务器负载较小。基于以上基础综合分析后,负载均衡设置会将缓存服务器的IP地址返回给用户。用户向缓存服务器发出请求。缓存服务器响应用户的请求,将用户需要的内容传递给用户。如果这台缓存服务器上没有用户想要的内容,但是负载均衡设备还是分配给了用户,那么这台服务器就会向它的上级缓存服务器请求内容,直到可以追溯到源服务器网站的本地拉取内容。缓存规则第一次访问,将网站的静态资源(如:JS、CSS、图片等)下载到本地浏览器,第二次访问从缓存中加载资源,不再请求服务器,提高网站访问速度使用CDN当浏览器缓存过期时,浏览器不直接向原站点请求资源,而是向最近的CDN站点请求。最近的CDN站点也有一个缓存。如果缓存过期,就近的CDN站点向原站点发送请求获取最新的资源。CDN节点缓存机制在不同的服务商。有所不同,但一般遵循HTTP协议,通过http响应头中的Cache-Control:max-age字段设置CDN节点文件缓存时间。当客户端向CDN节点请求数据时,CDN会判断缓存的数据是否过期。如果没有,则直接将缓存的数据返回给客户端。否则,它会向源站发送请求,从源站拉取最新的数据,并更新本地的Cache,将最新的数据返回给客户端。CDN的缓存时间会直接影响“回源率”。如果CDN缓存时间短,数据会经常失效,导致频繁回源,增加源站负载,也会增加访问延迟;如果缓存时间长,数据更新时间慢,需要根据不同的业务需求选择具体的数据缓存管理。例如:我们可以增加CDN的缓存时间,然后通过版本号控制导入的前端资源;如果有更新,直接更新资源后面拼接的版本号;当浏览器加载资源时,资源URL参数发生变化,形成一个新的资源链接,即到附近的CDN站点请求,找不到资源时,再到原站点请求最新的资源更新。