资源转载引入
web缓存
- web缓存主要包括两部分
- 浏览器缓存(localStoorage,sessionStorage,cookie)
- http缓存(强缓存,协商缓存)
浏览器缓存
- 相同点
- localStoorage,sessionStorage都是用来存储客户端数据的,被称为前端缓存或webStorage
- 存储大小都是5M
- 都只能存储字符串类型的数据
- 区别
- 通信问题
- sessionStorage不可进行跨页面客户端通讯(不过同页面下嵌套的iframe属于同源,可以通讯),不参与服务器通信
- cookie参与服务器通信,每次都会携带在http头中,如果使用过多数据会带来性能问题
- 生命周期
- sessStorage生命周期基于浏览器页面,存储的数据会在页面关闭时自动清除,刷新不会消失,同一页面不同窗口也不同
- localStoorage除非我们手动清除,不然不会消失
- cookie生命周期和设置的过期时间有关,存放大小只有4k左右
- 应用场景
- localStoorage长期有效的自动登录
- sessStorage短期有效的自动登录
http缓存
- 缓存目标
- 主要是针对html,css,img等静态资源,缓存动态资源会影响数据的实时性
- 优缺点
- 减少不必要的网络传输,节约宽带(就是省钱)
- 更快的加载页面(就是加速)
- 减少服务器负载,避免服务器过载的情况出现。(就是减载)
- 占内存(有些缓存会被存到内存中)
- 流程图

强制缓存
- 基于Expires
- 设定一个强缓存时间。在此时间范围内,则从内存(或磁盘)中读取缓存返回
- 过渡依赖本地时间,如果本地时间与服务器不同步,则可能出现无法命中缓存问题或者永远命中缓存问题。
- 已经废弃,除非需要向下兼容使用
- 基于Cache-control
- 属性
- max-age:决定客户端资源被缓存多久
- s-maxage:决定代理服务器缓存的时长
- no-cache:表示是强制进行协商缓存(跳过强缓存)
- no-store:是表示禁止任何缓存策略
- public:表示资源即可以被浏览器缓存也可以被代理服务器缓存
- private:表示资源只能被浏览器缓存(默认值)
- 示例:
Cache-Control:max-age=N,N就是需要缓存的秒数。从第一次请求资源的时候开始,往后N秒内,资源若再次请求,则直接从磁盘(或内存中读取),不与服务器做任何交互。
- 强缓存的问题
- html页面一般不做强缓存,每一次html的请求都是正常的http请求
- 服务器更新资源之后,让资源名称和之前不一样,这样页面都是最新资源(webpack打包的时候会生成文件名hash name)
协商缓存
- 基于last-modified(基于时间戳)
- 实现方式
- 首先需要在服务器端读出文件修改时间
- 将读出来的修改时间赋给响应头的
last-modified字段 - 最后设置
Cache-control:no-cache - 客户端读取到
last-modified的时候,会在下次的请求标头中携带If-Modified-Since - 服务端对比两个修改时间,决定是读取缓存还是返回新资源
- 缺点
- 如果是文件名更改,不是内容改变,修改时间也会变化
- 如果修改时间非常非常短,服务器没法对比,也不会返回最新资源
- 实现方式
- 基于Etag(基于文件指纹--文件哈希值)
- 实现方式
- 第一次请求某资源的时候,服务端读取文件并计算出文件指纹,将文件指纹放在响应头的etag字段中跟资源一起返回给客户端
- 第二次请求某资源的时候,客户端自动从缓存中读取出上一次服务端返回的ETag也就是文件指纹。并赋给请求头的
if-None-Match字段,让上一次的文件指纹跟随请求一起回到服务端 - 服务端拿到请求头中的
is-None-Match字段值(也就是上一次的文件指纹),并再次读取目标资源并生成文件指纹,两个指纹做对比。如果两个文件指纹完全吻合,说明文件没有被改变,则直接返回304状态码和一个空的响应体并return。如果两个文件指纹不吻合,则说明文件被更改,那么将新的文件指纹重新存储到响应头的ETag中并返回给客户端
- 缺点
- 服务端计算文件指纹需要更多开销,影响性能
- 强验证,哪怕文件中只有一个字节改变了,也会生成不同的哈希值,非常消耗性能,弱验证只提取部分文件属性计算哈希值,整体速度快,准确率不高
- 实现方式
总结
- 有哈希值的文件设置强缓存即可。没有哈希值的文件(比如
index.html)设置协商缓存 - http缓存可以减少宽带流量,加快响应速度
- 关于强缓存,cache-control是Expires的完全替代方案,在可以使用cache-control的情况下不要使用expires
- 关于协商缓存,etag并不是last-modified的完全替代方案,而是补充方案,具体用哪一个,取决于业务场景
- 有些缓存是从磁盘读取,有些缓存是从内存读取,有什么区别?答:从内存读取的缓存更快