🚀前端缓存
前端缓存分为浏览器缓存和http缓存,浏览器缓存例如web Storage,cookie等。复杂的是http缓存,分为强缓存与协商缓存两种缓存策略
当然第一次进入一个网站没有缓存的概念,但是根据第一次返回的响应字段,可以得到对应的缓存策略,得益于缓存策略,第二次乃至以后进入网站速度大大提升。
强缓存
对应着这两个字段:HTTP/1.0时期,使用的是Expires,而HTTP/1.1使用的是Cache-Control
- Expires:服务端会返回缓存的过期时间点,超过这个时间点缓存失效。但是服务端与浏览器的时间可能不一致,会产生问题,所以被Cache-Control取代
- Cache-Control:不是返回时间点而是持续时间
其下并不只有这一个属性,还有一些其他属性
- no-cache:跳过强缓存,走协商缓存
- no-store:强,协商缓存都没有
当Expires和Cache-Control同时存在的时候,Cache-Control优先级高
如果第二次进入到这个页面,执行缓存策略,第一步就是先判断强缓存,也就是 浏览器 根据返回的强缓存对应字段,判断缓存是否过期,如果没有过期,直接取缓存,不需要再进行协商缓存。
🚀
需要补充的是强缓存不需要发送http请求,虽然返回状态码还是200。另外这里的来源是内存/磁盘,并且只要是从内存/磁盘获取的就是走了强缓存。
协商缓存
从 协商 的字面意思上可以看出至少是需要两个人才能协商,也就是这里浏览器还要询问远程服务器缓存是否过期,也有两个字段
- Last-Modified:服务器把这个字段返回,下一次浏览器发送http,会在请求头将他带上,只不过字段名改成了If-Modified-Since,接着服务器判断这个时间是否过期,如果返回304代表未过期,否则返回新资源。
🚀弊端
last-modified 是一个时间,最小单位为秒,试想一下,如果资源的修改时间非常快,快到毫秒级别,那么服务器会误认为该资源仍然是没有修改的,这便导致了资源无法在浏览器及时更新的现象。 另外还有一种情况,比如服务器资源确实被编辑了,但是其实资源的实质内容并没有被修改,那么服务器还是会返回最新的 last-modified 时间值,但是我们并不希望浏览器认为这个资源被修改而重新加载。
- ETag:服务器根据文件内容生成的唯一标识。服务器把这个字段返回,下一次浏览器发送http,会在请求头将他带上,字段名改成了If-None-Match,服务器接着会跟服务器上该资源的ETag进行比对,如果返回304代表未过期,否则返回新资源。
🚀
etag也有强弱校验之分,弱校验前面会加上W/,区别是弱校验适应于内容格式发生变化但语义不变的情况下,强校验则会严格控制每个字节
如果强缓存判断过期了,就会进入协商缓存,此时会发送http请求,请求头上会加上If-Modified-Since,If-None-Match,他们的值就是第一次返回的响应标头中的Last-Modified,Etag。如果返回304代表缓存没过期,否则返回200,服务器返回最新资源。
启发式缓存
HTTP 旨在尽可能多地缓存,因此即使没有给出 Cache-Control,如果满足某些条件,响应也会被存储和重用,也就是启发式缓存
补充
项目通过jekins上部署之后,刷新页面还是原来的内容,这应该也跟缓存有关
注意到浏览器的刷新有三种,正常重新加载,硬性重新加载,清除缓存并硬性重新加载
正常重新加载也就是只是重新加载页面而已,缓存有效还是照用
硬性重新加载会在请求头上加一个cache-control:no-cache,cache-control一般是放在服务器的响应头上,但如果是在请求头上,no-cache允许客户端请求最新的响应即使保存的缓存是新鲜的
并且请求头里也没有协商缓存相关的字段,所以强缓存和协商缓存都没有走。其效果类似于在开发者工具 Network 面板勾选了 Disable cache 选项
清除缓存并硬性重新加载则是额外将我们保存的缓存删除
localStorage 和 sessionStorage
- localStorage数据会一直保存,而sessionStorage关闭页签或者窗口会就会删除
- localStorage同源的所有页签和窗口共享数据,sessionStorage仅在同一页签内共享数据
- localStorage一般用来保存登录token,用户信息等,sessionStorage则适用于用户暂存的表单等