线上环境在一次版本发布后,部分用户反馈出现白屏问题。此次发布新增了友盟(umeng)监控用于检测页面白屏情况,但实际效果并不理想,只能通过分析慢加载页面数据间接排查问题。

初期排查主要聚焦于前端代码层面(确实也存在部分问题,原代码缺乏状态管理和错误捕获机制,导致难以准确定位白屏发生的具体阶段)。这种偶发性白屏的主要难点在于难以稳定复现和精准定位原因。

经过第一轮优化(添加页面加载状态管理和JS异常捕获)并发布后,持续观察一天,发现相较之前有更多用户报白屏问题。并且通过部分用户提供的白屏截图来分析,发现页面并未显示新增的"加载中..."状态提示,这表明问题可能不在页面代码执行层面,而是更早期的资源加载阶段。

基于这些线索,推测问题根源可能是版本发布后的浏览器缓存机制导致。找了很久资料,我推测是微信的强缓存特性导致,会缓存入口文件index.html。当新版本发布后,部分用户浏览器中的缓存版本index.html仍引用旧版本的JS资源路径,导致资源加载失败,最终表现为白屏。

(每次打包后js文件后的hash数都不同,所以旧index.html引用旧hash数的js文件,但旧hash数的文件已经被删除,导致引用404报错。当时还想着发生产的时候把新包的文件夹直接拖入到服务器中用覆盖旧文件的形式更新版本,而不是删除旧文件后再拖入新文件,这样就不会删除掉旧的js文件,就算有缓存也没关系,只是说会导致文件越来越多,每次发布都要多一倍的js文件,因此作为优先级比较后的方法考虑)

1. 关于微信浏览器强缓存
   - 不仅是微信浏览器,支付宝浏览器、QQ浏览器等移动端浏览器都有类似的强缓存机制
   - 问题不仅限于index.html,其他关键资源(如vendor.js、manifest.js等)也可能被缓存
   - 强缓存并非微信浏览器独有特性,而是HTTP协议标准行为,只是微信浏览器可能缓存策略更激进

2. 关于白屏原因:
   - 除了缓存问题,还可能是CDN缓存、Service Worker缓存、网络环境等多种因素共同作用
   - 资源加载失败不一定是路径错误,也可能是资源内容不匹配(如旧HTML引用新JS,但JS接口已变更)

最终结果:一系列排查后,尝试了

  1. 前端代码接入友盟观察(uniapp在打包的时候也会提示一个类似友盟功能的勾选项,这次没用过,有机会可以试试)
  2. 优化前端代码,给慢加载的页面 加入错误捕获和页面加载状态.
  3. 优化前端代码,修改了友盟上捕获到的一些js错误
  4. 后端负责修改扫码进入的重定向地址时间戳添加,因为h5页面扫码进的话要先经过服务端一次重定向,其他需要加时间戳页面由前端在App.vue里处理(清除浏览器缓存),前端检查有加时间戳的页面(看看有没有从地址拿参数的逻辑),保证原来的逻辑不受影响
  5. 调整了接口响应超时时间(uniapp默认60s)
  6. 用了uniapp的摇树treeShaking优化打包体积,只减了100kb左右(原900kb左右)
  7. 服务器开启gzip压缩文本文件(如HTML/CSS/JSON),缩减了60%左右的包大小

最终的解决方案是6.服务器gzip压缩资源文件,缩减了60%左右的包大小

因为后面发现月底是最多用户白屏的时间点,合理怀疑是限流导致压缩前的资源拉取不下来,最后尝试6.7也是大幅减少了用户白屏反映,这次解决问题的方案虽然和前端没太大关系,但也是一次宝贵的排查白屏经验,因此记录

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐