梳理下前端能接触到的关于缓存的方式,比较开放有不全的小伙伴们帮忙补充。
HTTP缓存
http相关缓存包含2种:
- 强制缓存
- Expires:http1.0时代产物,response header里的过期时间,浏览器再次加载资源时,如果在这个过期时间内,则命中强缓存。
- Cache-Control:常见的取值有private、public、no-cache、max-age,no-store,默认为private。
- max-age=xxx,表示缓存多少秒
- no-store 表示缓存都不生效,不管是强制缓存,还是协商缓存
- no-cache 需要使用协商缓存来验证缓存数据。先与服务器确认返回的响应是否被更改,如果之前的响应中存在ETag,那么请求的时候会与服务端验证,如果资源未被更改,则可以避免重新下载。
- Pragma:http1.0时代的产物,理论上等于Cache-Control=no-cache,但是HTTP的响应头不支持这个属性,所以它不能拿来完全替代HTTP/1.1中定义的Cache-control头
- 协商缓存
- Last-Modified/If-Modified-Since:
- Last-Modified:服务器在响应请求时,告诉浏览器资源的最后修改时间。
- If-Modified-Since:当浏览器再次请求该资源时,request的请求头中会包含If-Modify-Since,该值为缓存之前返回的Last-Modify。服务器收到If-Modify-Since后,根据资源的最后修改时间判断是否命中缓存。已改动http状态变为200,未改动为304。
- ETag/If-None-Match:优先级高于Last-Modified,并且是http1.1的产物。
- ETag:服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定)。响应头是一个对用户代理(User Agent, 下面简称UA)不透明(译者注:UA 无需理解,只需要按规定使用即可)的值。
- If-None-Match:再次请求服务器时,通过此字段通知服务器客户段缓存数据的唯一标识。已改动http状态变为200,未改动为304。
浏览器中可用的存储
需要自己通过这些存储机制来设计缓存
- cookie
- 一般浏览器存储cookie 最大容量为4k,所以大量数据不要存到cookie。
- 每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题。
- 过期时间通过Expires来设置,默认关闭浏览器失效。
- 如果头部包含httponly,document.cookie不可以修改。
- localStorage
- 5MB左右
- 不会带到http头中
- 永久存在,需要手工触发清理。
- 无法阻止js修改
- sessionStorage
- 5MB左右
- 不会带到http头中
- 仅在当前会话下有效,关闭页面或浏览器后被清除。
- 无法阻止js修改
- Web SQL Database
- 已经被放弃。不过兼容性还可以
- indexedDB
- 支持事务、游标、索引等数据库操作
- 存储空间大
- 永久存储,删除缓存不干扰IndexedDB
- 异步性