当前位置: 首页 > 后端技术 > Node.js

缓存·面试知识必备!看这些就够了

时间:2023-04-03 23:57:10 Node.js

首发地址:https://mp.weixin.qq.com/s/wV...”对于一些前端er来说,实际接触缓存的实际操作并不多,既熟悉又陌生的技术点,笔者在这里介绍了常用的缓存相关基础知识和常见案例,日常场景下你都能掌握。为什么要使用缓存?如何结合实际正确使用缓存?带着这些问题开始写~重温1.cache-control:_no-cache|max-age|no-store|must-revalidate|public|private_max-age:表示缓存的有效时间;之后必须向服务器发起验证请求;2.HTTP规范规定验证请求失败时可以使用过期的缓存,must-revalidate对这种特殊情况有很强的约束case:只要资源过期,没有通过服务器的验证,就不能使用缓存失效no-cache:会缓存,但每次都会先验证;相当于max-age:0,must-revalidate.no-store:不允许对资源进行缓存;常见的比如浏览器的[Forward/Back],即使设置了no-cache,也会不验证就使用缓存,所以最好要用no-store,自然不用cachingcachepublic/private:区别在于资源是否是客户的隐私敏感数据。如果是,则使用private,不能被代理服务器缓存,即私有缓存;否则,它可以是公共缓存。[扩展]no-cache存储策略等同于http1.0中的Pragma:no-cache;max-age过期策略等同于http1.0中的expires;如果两者都存在,则前者具有更高的优先级。cache-control和pragma是公共头字段,响应时设置缓存;可以在请求时指明是否使用缓存,比如当浏览器开启disablecache时,请求头会加上:param:no-cache;缓存控制:无缓存;。一般禁止缓存的方式是:cache-control:no-cache,no-store,must-revalidate;(三者互补)如果没有设置缓存过期策略,浏览器会使用启发式算法计算缓存时间(与last-modified相关)。2.电子标签|Last-ModifiedETag的优先级高于Last-Modified。ETag:服务器资源的唯一标识相关请求头字段:if-match、if-none-matchLast-Modified:资源的最后修改时间。相关请求头字段:if-modified-since,if-unmodified-since精确粒度为秒,不适合短时间内频繁变化的资源。由于采用目前的构建打包方式,会出现资源内容没有变化,但是文件的修改时间发生了变化的情况。3、强缓存/协商缓存强缓存:expires,cache-control:max-age=100协商缓存:ETag,last-modified4。扩展字段Date:响应消息的生成时间。Age:当资源已经缓存在代理服务器上时,资源发布的性能优化&推荐的通用优化思路为了避免不必要的请求,建议对静态资源使用缓存;缓存带来更新问题(资源修改后如何通知浏览器获取最新的资源?)对策:资源更新时更改资源链接,避免命中缓存。比如在资源链接后面添加随机或者版本信息作为参数;(html是入口文件,最好不要缓存,保证访问的都是最新的资源)但是每次出一个版本都会更改所有链接,导致资源不变。请求资源采用更精确的控制,使用文件摘要hash作为文件名,只有修改后的文件名会发生变化,需要重新请求最新的资源目前静态资源往往部署到CDN,这会导致在发布方式和顺序:如果一个机器一个一个发布,会导致用户被导流到发布的机器获取最新的html,但是静态资源请求会被导流到其他未发布的机器,导致404;有两种解决方法:如果先发布html页面,用户获取最新的静态资源时会出现404;因此,建议先发布静态资源;静态资源叠加发布可能导致旧html获取旧静态资源404;所以最好使用增量发布(非覆盖型)由于使用集群,设置sticky为ngix,即第一次导流到哪台机器,之后一直访问该机器;先将集群中的静态资源全部释放,结合webpack的优化建议。一般在打包资源的时候,文件名会加上hash值,保证内容的改变会改变资源url,这样浏览器就不会命中缓存发起请求获取新的资源。那么可以为此类资源设置更长的缓存时间,一般为:cache-control:max-age=365*24*60*60;webpack优化建议,将代码拆分成合适的粒度,即降低缓存粒度,当代码发生变化时,影响较小;webpack动态加载的使用:import(),提前获取,实际使用时直接从缓存中读取常见的case。说到缓存问题,排查问题的思路。1、【案例一】常见场景:部分用户打开页面点击文件链接下载时,发现下载的资源是旧资源。但是对于浏览器来说,链接还是一样的,如果设置了缓存,就会命中缓存,使用旧的资源。解决方法:1)临时解决方法:清除缓存,刷新页面重新下载情况下会漏缓存。2、【案例2】node项目本地测试修改静态资源后,每次请求中仍然显示旧资源。分析一:考虑浏览器缓存。-控制:无缓存;Parama:no-cache)现象:仍然返回旧资源分析2:资源返回状态码200non-cachedread,说明问题不在浏览器,而在服务端;但是public下面的资源是最新的,服务器是从哪里读取旧的资源返回的呢?解决方案:显然服务器读取了内存缓存。项目采用egg,如果在config中静态设置buffer:true,资源会缓存在内存中,避免每次请求都通过文件流读取文件;这里,设置buffer为false(默认false)现象:问题解决。提示:这种情况下,需要在本地连接测试环境更新资源进行调试,获取最新反馈后,才需要关闭缓存。在线环境最好开启缓存。3、【注1】浏览器前向/后向,如果有缓存,即使缓存无效,也会直接使用,不与服务器核对。注意使用cache-control:no-cache不能解决这个问题,因为它相当于max-age=0,must-revalidate;,资源还是会被缓存。解决方法:只有使用no-store的时候才不会缓存资源。4.【注2】用户行为对缓存使用的影响地址栏输入/转发/后端:不管缓存是否过期,先尝试使用缓存。F5:协商缓存Ctrl+F5:强制不缓存获取新资源(请求头添加parama:no-cache;cache-control:no-cache)更多技术分享,欢迎扫码关注~