前端缓存
HTTP缓存:在HTTP请求传输时用到的缓存,主要在服务器代码上设置
浏览器缓存:浏览器缓存则主要由前端开发在前端js上进行设置
缓存的作用
性能优化,缩短网页请求资源的距离,减少延迟,并且由于缓存文件可以重复利用,还可以减少带宽,降低网络负荷。
数据请求分为:网络请求、后端处理、浏览器响应三个步骤。
浏览器缓存可以在第一和第三步骤中优化性能。比如,直接使用缓存而不发起请求,或者发起了请求但后端存储的数据和前端一致,那么就没有必要再将数据回传回来,这样就减少了响应数据。
由上图我们可以知道:
浏览器每次发起请求,都会先在浏览器缓存中查找该请求的结果以及缓存标识
浏览器每次拿到返回的请求结果都会将该结果和缓存标识存入浏览器缓存中
强制缓存:向浏览器缓存查找该请求结果,并根据该结果的缓存规则来决定是否使用该缓存结果的过程,强制缓存的情况主要有三种,如下:
①不存在该缓存结果和缓存标识,强制缓存失效,则直接向服务器发起请求(跟第一次发起请求一致),如下图:
②存在该缓存结果和缓存标识,但该结果已失效,强制缓存失效,则使用协商缓存,如下图
③存在该缓存结果和缓存标识,且该结果尚未失效,强制缓存生效,直接返回该结果,如下图
那么强制缓存的缓存规则是什么?
Expires是HTTP/1.0控制网页缓存的字段,其值为服务器返回该请求结果缓存的到期时间,即再次发起该请求时,如果客户端的时间小于Expires的值时,直接使用缓存结果。
到了HTTP/1.1,Expire已经被Cache-Control替代,原因在于Expires控制缓存的原理是使用客户端的时间与服务端返回的时间做对比,那么如果客户端与服务端的时间因为某些原因(例如时区不同;客户端和服务端有一方的时间不准确)发生误差,那么强制缓存则会直接失效,这样的话强制缓存的存在则毫无意义。
在HTTP/1.1中,Cache-Control是最重要的规则,主要用于控制网页缓存,主要取值为:
public:所有内容都将被缓存(客户端和代理服务器都可缓存)
private:所有内容只有客户端可以缓存,Cache-Control的默认取值
no-cache:客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定
no-store:所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存
max-age=xxx (xxx is numeric):缓存内容将在xxx秒后失效
例子,如下:
由上面的例子我们可以知道:
①HTTP响应报文中expires的时间值,是一个绝对值
②HTTP响应报文中Cache-Control为max-age=600,是相对值
由于Cache-Control的优先级比expires高,那么直接根据Cache-Control的值进行缓存,意思就是说在600秒内再次发起该请求,则会直接使用缓存结果,强制缓存生效。
注:在无法确定客户端的时间是否与服务端的时间同步的情况下,Cache-Control相比于expires是更好的选择,所以同时存在时,只有Cache-Control生效。
思考:浏览器的缓存存放在哪里,如何在浏览器中判断强制缓存是否生效?
状态码为灰色的请求则代表使用了强制缓存,请求对应的Size值则代表该缓存资源存放的位置,分别为memory cache 和 disk cache。
问题:那么memory cache 和 disk cache又分别代表的是什么呢?什么时候会使用disk cache,什么时候会使用memory cache呢?
cache.delete(resource)
或者容量超过限制,被浏览器全部清空。- | memory cache | disk cache |
---|---|---|
相同点 | 只能存储一些派生类资源文件 | 只能存储一些派生类资源文件 |
不同点 | 退出进程时数据会被清除 | 退出进程时数据不会被清除 |
存储资源 | 一般脚本、字体、图片会存在内存当中 | 一般非脚本会存在内存当中,如css等 |
原因:
浏览器读取缓存的顺序:
Service Worker 是否命中缓存,没有调用 fetch 函数,缓存查找。
缓存查找优先级:memory –> disk->push –> 服务器请求。(应该是Service Worker开始。。有点不太懂Service Worke)
页面缓存读取问题分析:
首次访问页面: 服务器请求
关闭博客的标签页,重新打开页面:内存缓存被清除,会读取硬盘的缓存
刷新页面:内存缓存没有被清除,读取内存缓存,读取硬盘缓存
①协商缓存生效,返回304,如下
②协商缓存失效,返回200和请求结果结果,如下
协商缓存的标识也是在响应报文的HTTP头中和请求结果一起返回给浏览器的,
控制协商缓存的字段分别有:Last-Modified / If-Modified-Since和Etag / If-None-Match,其中Etag / If-None-Match的优先级比Last-Modified / If-Modified-Since高。
注:Etag / If-None-Match优先级高于Last-Modified / If-Modified-Since,同时存在则只有Etag / If-None-Match生效。对于协商缓存,使用 Ctrl+F5强制刷新可以使得缓存无效。但是对于强缓存,在未过期时,必须更新资源路径才能发起新的请求(更改了路径相当于是另一个资源了,这也是前端工程化中常用到的技巧)。
我们既希望缓存能在客户端尽可能久的保存,又希望它能在资源发生修改时进行及时更新。
cache-control:max-age=86400
style.css
:由于其属于文本文件,可能存在内容的不定期修改,又想使用强制缓存来提高重用效率,可以考虑在样式表文件的命名中增加文件指纹或版本号(比如添加文件指纹后的样式表文件名变为了style.51ad84f7.css
)。请求的文件 URL 不同了,因此必然会发生对资源的重新请求。同时考虑到网络中浏览器与CDN等中间代理的缓存,其过期时间可适当延长到一年,即cache-control:max-age=31536000
。cache-control:private
。Cookie:主要用于用户信息的存储,Cookie的内容可以自动在请求的时候被传递给服务器。
LocalStorage:它的数据将一直保存在浏览器内,直到用户清除浏览器缓存数据为止。
SessionStorage:属性LocalStorage一样,但是它生命周期同标签页的生命周期,当标签页被关闭时,SessionStorage也会被清除。
往返缓存又称为BFCache,是浏览器在前进后退按钮上为了提升历史页面的渲染速度的一种策略。
该策略具体表现为,当用户前往新页面时,将当前页面的浏览器DOM状态保存到BFCache中;当用户点击后退按钮的时候,将页面直接从BFCache中加载,节省了网络请求的时间。
大部分转自作者:Thomas赵骐
原文链接:https://www.jianshu.com/p/256d0873c398
学习资源:
原文:https://www.cnblogs.com/jiajia-hjj/p/15207908.html