一个前端pre-fetch和nginx设置不当导致的生产事故

280 阅读3分钟

分享一个前端pre-fetch和nginx设置不当导致的生产事故

大家好,我是魔性的茶叶,今天分享个前端性能优化导致的生产事故,虽然我不是干前端的,但是这件事从头到尾分析下来还是很有意思的,分享给大家。感谢@rhymedys_师兄全程分享!

现象

image-20221205105807688

首先先讲现象,某日晚前端工程升级当天没有任何问题,第二天早上一来直接所有用户打开我们的前端应用大面积白屏,基本需要等待一两分钟才能打开,加上用户超百万之巨,接下来当然是铺天盖地的反馈和客诉。

当场措施

页面白屏loading一段时间后加载出来,那么一般都是前端问题。因为前一天晚上升级了前端,所以紧急回滚前端到上一版本。回滚到上一版本的前端后少了90%的前端白屏,基本算是解决。

排查问题

增加前端pre-fetch请求

既然问题在前端上,那么看看前端昨晚升级了什么。询问前端发现前端对项目资源的加载使用了pre-fetch技术,简单的了解一下前端的pre-fetch技术(前端的pre-fetch技术:blog.csdn.net/weixin_4579…),意思大概是指浏览器会在自己空闲的时候去把整个网站的资源加载进来,这样子用户访问其他页面的时候因为有了缓存会快很多,按照现在大部分用户的机器(手机+pc)来说,浏览器的性能都是过剩的,也就是说大部分时间是空闲的,就是说用户下一次进入应该是直接就有缓存的,理论上是一个很不错的优化。

nginx设置js不缓存

既然前端pre-fetch是一次很好的优化,那么为啥用户进入页面需要加载一到两分钟,一副没有缓存的样子呢,这就要提到我们另一个操作,那就是nginx设置了js不缓存,我们知道,前端设置html不缓存是合理的。因为每次前端打包前端的js文件名都会改变,并且html的文件大小一般是不大的,所以设置不缓存没啥问题(大的是js和css这些资源文件),这次设置js不缓存是为了排查之前前端的一些问题。

总流程

但是关键就在这里,pre-fetch+nginx设置js不缓存,导致了前端请求的流量飙升。我们从头捋一下,pre-fetch在空闲的时候去加载项目内的资源,但是nginx又告诉浏览器不必缓存js,也就是说pre-fetch拉取到js后,过一会这个js就又没了(因为nginx告诉浏览器不必缓存),然后pre-fetch又去拉取js,成了个无解的死循环,也就是假如有500w个客户端,假如一小时内pre-fetch三次,那么请求静态资源是500w*3次,这个流量比较恐怖,导致我们的cdn直接负载不过来了,所以即使用户进入到首页只加载到首页这么少的资源cdn还是反应不过来。

后期整改

  1. 前端调整不使用pre-fetch预加载。
  2. nginx设置html不缓存,js css等缓存。

总结

pre-fetch是一个好的优化,如果用的好的话是很好的性能优化。

nginx一定要设置前端资源除html以外的静态资源(如js+css)的缓存,避免不缓存的带来的性能问题。