浏览器缓存最佳实践

1,750 阅读2分钟

最佳实践

上来先说结论,原因放在后面:

  1. index.html 不做缓存,每次请求都获取最新版本
  2. 使用 webpack 等 build 后的其他所有资源文件(包括 js、css 和图片等),都做强缓存(一个月打底,可以设置一年)

原因

强缓存和协商缓存在社区已经被写烂了,都知道是怎么回事,这里就不做详细解释了,这里解释下为什么说上面的是最佳实践。

我们知道协商缓存其实也向服务端发起了一个请求,只不过最后经过一系列验证,结果就是不传输具体内容了,但是验证的过程也给后端造成了一些开销,所以我们要尽量减少这种开销。

那么把前端资源都用作强缓存就是最好的处理办法了,但是又面临一个问题『前端发版怎么更新』

这时候我们需要注意 build 后的前端资源,现在各个脚手架默认都会把文件名字生成一段 hash 值 xxx.6ae44c4e.js这种。原来我一直不明白这样的意义在哪,现在明白了。

首先 index.html 不做缓存,所以当我们发版以后浏览器会获取到最新的 index.html 文件,由于每次 build 之后生成的文件名字不同,index.html 引入的前端的资源就不同,旧的所有的资源文件包括 js、css 和图片等)都不会影响新发版的内容。

这样的话就做到了在不发版的情况下,每次刷新基本就一个 index.html 的资源还有一些接口请求,其余的全都是强缓存资源。发版之后可以立马更新,不会造成资源混乱。现在掘金和 segmentfault 都是采取的这种策略。

实践数据对比

强缓存
强缓存

和运维的同事商量了强缓存的优化,将 build 之后的 static 文件夹全部做了 add_header Cache-Control "max-age=30243600",也就是强缓存 30 天的设置。

经过测试发现,由协商缓存到强缓存后,有如下变化:

类型 请求数 实际传输资源大小 传输完毕(Finish) DOMContentLoaded Load
协商缓存 631 168K 2.00s 447 ms 717 ms
强缓存 631 23K 1.43s 424 ms 704 ms

结果分析

首先,请求数量是一样的,完全 Load 的时候差不多,Finish 的时间提升了 25%,传输的资源大小减少了 80% 以上,同时由于没有和服务端去进行协商,相当于对服务端也做了优化。这些都是在协商缓存的基础上做的优化对比,如果后端服务连协商缓存都没上的话,真的应该优化一下了。