如何优化静态资源部署?
如题所示,我们要解决的问题是如何优化静态资源部署?那么,在解决这个问题前,我们先问问为什么要优化静态资源呢?
上图是index.html和它的样式文件,我们把它们部署到服务器,等待用户访问。当用户访问时,我们可以看到网络请求状态码为200显示访问成功。但是,用户每一次的访问都需要加载静态资源,影响性能,浪费带宽。
于是,我们让浏览器使用本地缓存,这时候请求状态码为304,也就是使用了协商缓存。变成这样:
为了追求更极致的性能,我们希望再减少静态资源的加载速度。那么利用本地缓存,强制浏览器使用本地强缓存,不与服务器进行通信。变成这样:
稍微总结一下缓存的基本原理:
- 1)浏览器在加载资源时,根据请求头的
expires
和cache-control
判断是否命中强缓存,是则直接从缓存读取资源,不会发请求到服务器。 - 2)如果没有命中强缓存,浏览器一定会发送一个请求到服务器,通过
last-modified
和etag
验证资源是否命中协商缓存,如果命中,服务器会将这个请求返回,但是不会返回这个资源的数据,依然是从缓存中读取资源 - 3)如果前面两者都没有命中,直接从服务器加载资源
接下来,如果静态资源发生了更新,浏览器怎么知道并更新呢?
通过更新页面中引用的资源路径,让浏览器主动放弃缓存,加载新资源。好像这样:
每一次的更新我们只需要更换每一个静态资源的版本参数让浏览器放弃缓存即可。但是,静态资源的数量一般是很大的,而我们每一次更新的内容并不多,这样会造成一定的浪费。
于是我们使用数据摘要算法,对文件求摘要信息,那么每一个文件就有了缓存控制依据决定是否进行更新。
消息摘要算法:消息摘要算法的主要特征是加密过程不需要密钥,并且经过加密的数据无法被解密,只有输入相同的数据经过加密后才能得到相同的密文。
问题就得到解决了,我们可以利用本地缓存,优化静态资源的加载速度,若静态资源发生更新,我们可以放弃缓存,重新访问服务器拿静态资源。
当然还没有结束,现在公司使用CDN节点提高网站性能:把静态资源和动态网页分集群部署,静态资源被部署到CDN节点,页面中对资源的引用路径变为相应CDN结点的部署路径。
这样带来最后一个问题,我们应该先上线页面还是先上线静态资源。
无论哪一个先,都会造成页面错乱的问题,造成问题起源于资源的覆盖式发布,我们要使用非覆盖式发布!
看上图,用文件的摘要信息来对资源文件进行重命名,把摘要信息放到资源文件发布路径中,这样,内容有修改的资源就变成了一个新的文件发布到线上,不会覆盖已有的资源文件。上线过程中,先全量部署静态资源,再灰度部署页面,整个问题就比较完美的解决了。
总结:
-
配置超长时间的本地缓存
—— 节省带宽,提高性能
-
采用内容摘要作为缓存更新依据
—— 精确的缓存控制
-
静态资源CDN部署
—— 优化网络请求
-
更资源发布路径实现非覆盖式发布
—— 平滑升级