浅析实际场景如何应用缓存策略:项目中什么文件用强缓存什么文件用协商缓存

一、问题背景

1、我们经常说的强缓存和协商缓存,那么想一想在项目上,什么文件用强缓存?什么文件用协商缓存呢?那么我这里就来说一说。

  就拿前端SPA部署来说,打包过后的文件为 index.html、css、js、img 文件等,

(1)index.html 应该不缓存,或者是设置 no-cache 的强缓存(即资源被缓存,但立即失效,下次请求会验证资源是否过期)+ 协商缓存,保证 index.html 每次都从服务器获取最新的;

(2)js、css、img 等文件会在打包后生成对应的 hash 标识,所以这些文件可以设置一个比较长的缓存时间,比如1年;

2、那么 index.html 为什么不该缓存呢?

  因为他是应用的入口,只有加载它之后才会加载它引用的资源文件,如 css、js、img 等,所有要保证 index.html 不被缓存,这样你才能保证本地资源版本跟服务器一致。

  至于css、img、js等资源文件如果重新打包,那么他们的文件名也会根据内容发生变化(contentHash),都是不同的文件了也就不担心缓存带来的副作用了。

  也就是说 index.html,切记不要设置强缓存!!!其他资源采用强缓存 + 协商缓存。

3、为什么是强缓存 + 协商缓存呢?

  有这么一句话:“协商缓存需要配合强缓存使用”。

  因为我们经常看到的协商缓存中,除了Last-Modified这个header,还有强缓存的相关header,因为如果不启用强缓存的话,协商缓存根本没有意义。

  其实很好理解的哈,如果不开启强缓存,本地都没任何缓存,还“协商”个P啊,只能服务器读取了

二、缓存能起到什么作用?以及怎么做?

(1)降低带宽压力

(2)降低服务器处理压力

(3)加快页面渲染

  既然知道了为什么做,那么这个当然是越快越好,最好都缓存起来才好

  1. 能做强制缓存就强制缓存
  2. 不能做强制缓存就做协商缓存
  3. 无缓存的情况下,看看服务端能对高频文件做缓存吗

  但是事情往往没有这么简单,我们一般是 html 不缓存,资源强缓存(js、css,通过 hash 名来更新文件),接口的话一般不会做强缓存,配置啥的可以考虑一下协商缓存。逻辑处理之类的必须要准确数据,也就不会做缓存

  所以说我们的结论是:

  index.html 这个是入口文件,我们最好是做立即失效的强缓存 + 协商缓存,这样就可以保证资源更新,每次都请求到最新的

  资源之类的,比如打包后生成的 js、css、img 那些,可以使用强缓存,比如你们是半个月一发版,那设置一个月即可。因为他们是在 index.html 中去加载的,而如果文件变化的话,其 contenthash 值也会变化,就会变成不同的文件(所以这里加协商缓存也没啥作用,因为文件链接都变了),故不会有缓存的副作用

  而一些资源可能变,也可能不变的,比如放在 static 或 public 目录下的资源,因为它们是不参与 webpack 打包的,而是直接 copy,所以不会存在 contenthash 那些,故这类资源最好使用强缓存+协商缓存

三、实际场景应用缓存策略

1、频繁变动的资源:设置强缓存但让其立即失效,即 Cache-Control: no-cache,然后再配合协商缓存

  对于频繁变动的资源,首先需要使用 Cache-Control: no-cache 使浏览器每次都请求服务器,然后配合 ETag 或者 Last-Modified 来验证资源是否有效。这样的做法虽然不能节省请求数量,但是能显著减少响应数据大小。

2、不常变化的资源:设置强缓存 Cache-Control: max-age=31536000

  通常在处理这类资源时,给它们的 Cache-Control 配置一个很大的 max-age=31536000 (一年),这样浏览器之后请求相同的 URL 会命中强制缓存。而为了解决更新的问题,就需要在文件名(或者路径)中添加 hash, 版本号等动态字符,之后更改动态字符,从而达到更改引用 URL 的目的,让之前的强制缓存失效 (其实并未立即失效,只是不再使用了而已)。 在线提供的类库 (如 jquery-3.3.1.min.js, lodash.min.js 等) 均采用这个模式

四、用户行为对浏览器缓存的影响

  所谓用户行为对浏览器缓存的影响,指的就是用户在浏览器如何操作时,会触发怎样的缓存策略。主要有 3 种:

1、打开网页,地址栏输入地址: 查找 disk cache 中是否有匹配。如有则使用;如没有则发送网络请求。

2、普通刷新 (F5):因为 TAB 并没有关闭,因此 memory cache 是可用的,会被优先使用(如果匹配的话)。其次才是 disk cache。

3、强制刷新 (Ctrl + F5):浏览器不使用缓存,因此发送的请求头部均带有 Cache-control: no-cache(为了兼容,还带了 Pragma: no-cache),服务器直接返回 200 和最新内容

posted @ 2019-01-23 22:18  古兰精  阅读(1744)  评论(0编辑  收藏  举报