写这篇文章的缘由是最近在研究PWA如何在项目中落地实施,这就无可避免的须要接触到浏览器缓存的相关知识,所以特地写下这篇文章巩固下本身对浏览器缓存的认识。css
缓存是一种保存资源副本并在下次请求时直接使用该副本的技术。当web缓存发现请求的资源已经被存储,它会拦截请求,返回该资源的拷贝,而不会去源服务器从新下载。这样带来的好处有:缓解服务器端压力,提高性能(获取资源的耗时更短了)。web
咱们都知道浏览器是基于HTTP协议和服务端进行通讯的,一个网站一旦同时请求过多或者请求过大就容易形成页面渲染时长过长等性能问题,并且并不是全部资源都须要实时更新的,将长久或一段时间内的资源进行缓存,能很大的缓解服务器压力和提高网站性能。
绝不夸张的说,HTTP缓存是达到高性能的重要组成部分。浏览器
注意:缓存须要合理配置,由于并非全部资源都是永久不变的:重要的是对一个资源的缓存应截止到其下一次发生改变(即不能缓存过时的资源)。缓存
强缓存:Expires: Date/Cache-Control:max-age=N
协商缓存:Last-Modified:Date和Etag:String服务器
经过查询标准咱们知道Cache-Control和Etag属于HTTP1.1版本,Expires和Last-Modified属于HTTP1.0版本,因此得出如下优先级:
强缓存:Cache-Control > Expires
协商缓存:Etag > Last-Modified工具
注意:
Expires存在的缺陷是返回的到期时间是服务器端的时间,可能与客户端的时间有较大的时间差,因此在HTTP1.1版开始使用Cache-Control: max-age=秒替代
Last-Modified的缺陷:因为只能精确到秒,若是一个文件在1秒内屡次修改,这时客户端没法识别,所以HTTP1.1版本使用Etag标识资源内容是否有变动来确认资源是否须要更新,相对来讲更加精确性能
强缓存:资源一旦被强缓存,在缓存时间内,浏览器发起二次请求时会直接读取本地缓存,不与服务器进行通信。 强缓存时间过时的,浏览器会判断资源的响应头是否有Last-Modified和Etag字段,有的话执行协商缓存策略测试
协商缓存:若是响应头中的包括有Etag和Last-Modified字段,则客户端将If-None-Match:Etag的值和If-Modified-Since:Last-Modified的值添加到请求头发送给服务器,由源服务器校验,若是资源未过时则返回304状态码,浏览器直接使用缓存,不然返回200OK状态码和新资源。字体
当两种状况都存在时,强缓存优先级要高于协商缓存。网站
选择Chrome是由于它是如今最流行的网页调试工具也是最多人用的浏览器。 Chrome浏览器返回缓存http状态码总共有如下三个 一、200 from memory cache 客户端不与服务器通信,直接从内存中读取缓存。此时的数据时缓存到内存中的,当关闭浏览器后,数据天然就被当垃圾回收清空。
二、200 from disk cache 客户端不与服务器通信,直接从磁盘中读取缓存,由于数据存在磁盘中,就算关闭浏览器数据仍是存在,下次打开只要数据不过时就能够直接读取。
三、304 Not Modified 客户端与服务器通信,服务器验证资源是否须要更新,若是不须要更新服务器返回304状态码,而后客户端直接从缓存中读取数据
注意:通过测试,我发现Safari和Firefox都有三种缓存策略,IE和其余浏览器你们能够各自测试一下
Chrome和Safari彷佛没有办法在浏览器中直接查看缓存状况,所以只能实践中查看。 Chrome示例图: 状态码:200 OK
Safari示例图: 响应头:
Firefox:在url上输入about:cache 能够看到对应的缓存状况,你们能够试一下
我在网上看到有人写文章说 js、图片和字体保存在内存中而css则保存在磁盘,很明显,只要本身稍微测试一下就知道这种说法是站不住脚的,那么这三种状况到底是怎样的呢?
通过简单的测试之后我发现这三种策略并不复杂,默认配置状况下,Chrome第一次请求资源后,若是资源的响应头有Cache-Control或者Expires且有效期大于如今,则加载数据后将强缓存资源到内存和磁盘。
刷新页面,Chrome发起整个页面的二次请求后,经过开发者工具能够看到强缓存资源都会从内存进行读取,这就是200 from memory cache的状况。
示例:
这时关闭浏览器后,从新打开浏览器并打开关闭前的页面,经过开发者工具能够看到以前强缓存资源都会从磁盘中读取,这是由于关闭了浏览器后系统回收了内存资源,所以内存没有了以前的强缓存资源,须要从磁盘中读取,这就是200 from disk cache的状况。
示例:
若是这时使用ctrl + f5强刷页面则会发现所有资源都是200 OK状态要从服务器中获取新数据。
304 Not Modified的状况则彻底不一样,若是资源的响应头是Last-Modified或Etag,第一次请求资源后缓存到本地磁盘,但第二次也必须发起请求到服务器进行查询该资源是否过时或被修改过,当服务器验证资源没有过时后才会返回304 Not Modified状态码,同时响应体为空,这样能够节省流量并提升响应速度,客户端接收到304状态码后从本地读取数据,所以304比200 from cache响应速度要慢,但比200 OK快得多。
上述说法均为我的想法,若有不对,敬请指出,谢谢你们的阅读!