失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 浏览器缓存机制:强缓存和协商缓存

浏览器缓存机制:强缓存和协商缓存

时间:2018-12-17 00:31:43

相关推荐

浏览器缓存机制:强缓存和协商缓存

缓存

memory cache 是内存中的缓存,主要包含当前页面中已经下载的资源,比如样式、脚本、图片等等。读取内存中的数据肯定比磁盘块,但是内存缓存的时间段,会随着进程的是否而释放。一旦我们关闭 Tab 页面,内存中的缓存就被释放了。因为内存有限,并不是所有的资源文件都会放在内存里缓存,它主要用来缓存有 preloader 相关指令的资源,比如。preloader 可以一边解析 js/css 文件,一边网络请求下一个资源。

disk cache 也就是存在磁盘上的缓存,读取速度比 memory cache 慢点,但是所有的资源文件都可以存在磁盘里。在所有浏览器缓存中,disk cache 覆盖面最大,它会根据 HTTP Header 中的字段判断哪些资源需要缓存,哪些资源已经过期需要重新从服务器端请求。一般来说,大的文件和使用频率高的文件,会被优先放在磁盘里。

强缓存

强缓存是不会向服务器发送请求,直接从缓存中读取资源

1、Expires: Wed, 25 Sep 08:13:53 GMT

Expires 是 HTTP/1 的产物,受限于本地时间,如果修改了本地时间,可能会造成缓存失效。

2、Cache-Control: max-age=300

Cache-Control 是 HTTP/1.1 的产物,同时有 Expires 和 Cache-Control 的时候,Cache-Control 的优先级要比 Expires 要高,比如Cache-Control: max-age=300,表示这个请求的返回时间(浏览器会记录该时间)的五分钟之内再次加载该资源,就会从缓存中读取该文件,无需再次请求。

Cache-Control: no-cache/ private / public / no-store …

协商缓存

协商缓存是指在强缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识来决定是否使用缓存

1、协商缓存是利用的是【Last-Modified,If-Modified-Since】和【ETag、If-None-Match】这两对 Header 来管理的 ,ETag 的优先级要高于 Last-Modified。

2、但是 Last-Modified (跟时间)有两个弊端:

如果本地打开缓存文件,即使没有对文件进行修改,但还是会造成 Last-Modified 被修改,服务端不能命中缓存导致发送相同的资源因为 Last-Modified 只能以秒计时,如果在不可感知的时间内修改完成文件,那么服务端会认为资源还是命中了,不会返回正确的资源

3、 Etag 是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成),只要资源有变化,Etag 就会重新生成。浏览器在下一次加载资源向服务器发送请求时,会将上一次返回的 Etag值放到request header 里的 If-None-Match 里,服务器只需要比较客户端传来的 If-None-Match 跟自己服务器上该资源的 ETag 是否一致,就能很好地判断资源相对客户端而言是否被修改过了。如果服务器发现 ETag 匹配不上,那么直接以常规 GET 200回包形式将新的资源(当然也包括了新的 ETag)发给客户端;如果 ETag 是一致的,则直接返回304知会客户端直接使用本地缓存即可。

缓存机制总结

强制缓存优先于协商缓存进行,若强制缓存(Expires 和 Cache-Control)生效则直接使用缓存,若不生效则进行协商缓存(Last-Modified / If-Modified-Since和Etag / If-None-Match),协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么代表该请求的缓存失效,返回200,重新返回资源和缓存标识,再存入浏览器缓存中;生效则返回304,继续使用缓存。

如果浏览器没有设置缓存策略,缓存怎么处理?

缓存时间= (Response Date - Last Modified) % 10

用户行为对浏览器缓存的影响

所谓用户行为对浏览器缓存的影响,指的就是用户在浏览器如何操作时,会触发怎样的缓存策略。主要有 3 种:

打开网页,地址栏输入地址: 查找 disk cache 中是否有匹配。如有则使用;如没有则发送网络请求。普通刷新 (F5):因为 TAB 并没有关闭,因此 memory cache 是可用的,会被优先使用(如果匹配的话)。其次才是 disk cache。强制刷新 (Ctrl + F5):浏览器不使用缓存,因此发送的请求头部均带有 Cache-control: no-cache(为了兼容,还带了 Pragma: no-cache),服务器直接返回 200 和最新内容。

缓存的弊端

从缓存里拿文件肯定是要比从服务器上拿性能要高,但是也会有弊端。 比如一分钟前一个用户刚访问一个网站,这个时候浏览器缓存了一部分静态文件,这个时候这个网站发布了新版本包含一些新功能,那么在缓存不过期的情况下,这个用户永远都没法看到新版本新功能,除非这个用户强制清除他本地的缓存。 新版本发布以后,每次都需要用户清缓存,显然不合理。

解决方案:<script src="../js/app.min.js">第一种方案就是每次手动给这个文件加个版本号<script src="../js/app-v2.min.js">第二种方案就是每次对应静态文件里有内容改动的时候,自动加一段 hash 到静态文件名里

具体用法是在webpack配置文件的output filename中加上 [chunkhash]://webpack.prod.jsoutput: {path: path.join(process.cwd(), 'dist'),publicPath: "/dist/",filename: 'js/[name].[chunkhash].bundle.js',// filename: 'js/[name].[hash].bundle.js',}

hash与chunkhash的区别:

hash 是用来给本次build计算hashcode,所有的编译结果文件中的hashcode都会一样。

chunkhash 是用来给每个entry file计算hashcode,每个编译结果文件中的hashcode都是独一无二的。而且entry file任一文件改动,对应的bundle文件hashcode也会改动,否则就保持不变。

如果觉得《浏览器缓存机制:强缓存和协商缓存》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。