当前位置: 首页 > 科技观察

浏览器缓存解析,看完不懂就来打我!

时间:2023-03-19 18:51:21 科技观察

缓存概念浏览器缓存(BrowerCaching)是浏览器缓存之前请求过的文件,以便下次访问时重复使用,节省带宽,提高访问速度,减轻服务器压力http缓存机制主要在http响应头中设置,响应标头中的相关字段是Expires、Cache-Control、Last-Modified/If-Modified-Since、Etag/If-None-Match。缓存策略浏览器的缓存策略一般分为两种:强缓存和协商缓存1)浏览器加载资源时,根据请求头的expires和cache-control判断是否命中强缓存,并读取如果是这样,直接从缓存中获取资源。没有请求发送到服务器。2)如果没有命中强缓存,浏览器肯定会向服务器发送请求,通过last-modified和etag验证资源是否命中协商缓存。如果命中,服务器会返回请求,但不会返回该资源的数据。还是从缓存中读取资源3)如果前面两次都没有命中,则直接从服务端加载资源。强缓存不向服务器发送请求,协商缓存会向服务器发送请求。强缓存强缓存是通过Expires和Cache-Control两个响应头来实现的。ExpiresExpires是http1.0提出的一个header,用来表示资源过期时间。它描述了一个绝对时间并由服务器返回。Expires受当地时间限制。如果本地时间被修改,缓存可能会失效。Expires:Wed,11May201807:20:00GMTCache-ControlCache-Control出现在HTTP/1.1中,优先级高于Expires,表示相对时间Cache-Control:max-age=315360000Cache-ControlheaderCache-Control:no-store禁止所有的缓存(这个就是响应不缓存的意思)。缓存通常会将无存储响应转发给客户端,然后删除对象,就像非缓存代理一样。Cache-Control:no-cache强制客户端直接向服务端发送请求,也就是说每次请求都必须向服务端发送。服务器收到请求,然后判断资源是否发生变化,如果是则返回新的内容,否则返回304,不变。这很容易产生误解,让人误以为没有缓存响应。实际上,Cache-Control:no-cache会被缓存,但是每次向客户端(浏览器)提供响应数据时,缓存都必须评估缓存的响应对服务器的有效性。Cache-Control:max-age部分表示从服务器发送文档时起文档可以被认为是新鲜的秒数。Cache-Control:s-maxage和max-age一样,只是针对代理服务器缓存。Cache-Control:private只能被终端浏览器缓存(和私有缓存),中继缓存服务器不允许缓存。Cache-Control:public可以被所有用户缓存(多用户共享),包括终端和CDNs等中间代理服务器协商缓存当浏览器对某个资源的请求没有命中强缓存时,会向服务器验证协商缓存是否被命中。如果命中协商缓存,则请求响应返回的HTTP状态为304,并显示NotModified。字符串Last-Modified/If-Modified-SinceLast-Modified表示本地文件的最后修改日期。浏览器会在请求头中添加If-Modified-Since(上次返回的Last-Modified的值),询问服务器where日期之后资源是否有更新,如果有更新则发送新的资源返回,但是如果在本地打开缓存文件,Last-Modified会被修改,所以ETagETag/If-None-MatchEtag在HTTP/1.1中出现像指纹一样,资源变化会引起ETag变化,与最后修改时间无关。ETag可以保证每一个资源都是唯一的。If-None-Matchheader会将最后返回的Etag发送给服务器,询问资源的Etag是否有更新,如果有变化,会发回新的资源。ETag的优先级高于Last-Modified。具体使用ETag的原因主要是出于以下考虑:有些文件可能会周期性的改变,但是他的内容是不会改变的(只有改变的修改时间),这个时候我们不希望客户端认为文件已修改,重新GET;有些文件修改非常频繁,比如秒内,(比如说1s内修改了N次),If-Modified-Since可以检查的粒度是s级,这种修改不能判断(或者UNIX记录的MTIME只能精确到秒);部分服务器无法准确获取文件的最后修改时间。整体流程图第一次请求缓存解决的问题第一次请求不缓存减少冗余数据传输,节省你的网络成本。缓存缓解了网络瓶颈问题。页面加载速度更快,无需更多带宽。缓存减少了对原始服务器的需求。服务器可以更快地响应并避免过载。缓存减少了距离延迟,因为页面从更远的地方加载得更慢。缓存位置ServiceWorker(是运行在浏览器后面的独立线程,一般可以用来实现缓存功能,传输协议必须是HTTPS)MemoryCache这是内存中的缓存,大部分刷新页面的数据来自memorycache,read检索速度快,但容量小,持续时间很短。DiskCache会随着进程的释放而释放。这是存储在硬盘中的缓存。读取速度较慢,但??一切都可以存储在磁盘中。PushCacheThis是HTTP/2中的内容。当三种缓存都没有命中门时,就会使用它。缓存时间也很短。它只存在于会话中,一旦会话结束就会被释放。所有的缓存怎么会错过网络请求呢?,然后会发起请求获取资源。选择合适的缓存策略协商缓存需要与强缓存结合使用。如果不启用强缓存,协商缓存是没有意义的。大多数web服务器默认开启协商缓存,同时开启[Last-Modified,If-Modified-Since]和[ETag,If-None-Match]但以下场景需要注意:Last-Modifiedof分布式系统中多台机器之间的文件必须保持一致,以避免负载均衡到不同机器比较失败;分布式系统尽量关闭ETag(每台机器生成的ETag会不同);缓存策略webpack在实际场景中的hash值webpack为我们提供了三种hash值计算方式,分别是hash、chunkhash和contenthash。那么三者有什么区别呢?哈希关系到整个项目的建设。生成文件的哈希值相同。只要项目中有一个文件变化,整个项目的哈希值就会发生变化。chunkhash根据不同的入口文件(Entry)分析依赖文件,构造对应的chunk,生成对应的hash值。contenthash是文件内容生成的hash值,不同内容生成的contenthash值不同。显然,我们不会使用第一个。换了一个文件,打包之后,其他文件的hash都变了,缓存自然就失效了。这不是我们想要的。那么chunkhash和contenthash的主要应用场景有哪些呢?在实际项目中,我们通常会从项目中的css中提取出相应的css文件以供参考。如果我们使用chunkhash,当我们更改css代码时,会发现当css文件的hash值发生变化时,js文件的hash值也会发生变化。这时候contenthash就派上用场了。在webpack的打包策略下,我们基本都会对JS文件使用chunkhash,对CSS文件使用contenthash。综上所述,我们可以想出一个比较合理的缓存方案:HTML:使用协商缓存。CSS&JS&Image:使用强缓存,文件名带哈希值。作者:willghy链接:https://juejin.im/post/6867451120458694670来源:掘金版权归作者所有。商业转载请联系作者授权,非商业转载请注明出处。