记一次前端页面切换卡死的排查经历
这是一个老项目的新迭代,项目由element admin改编而来,bug的症状是:来回切换页面,有概率页面卡死。
我首先怀疑是内存泄漏导致了页面卡死,因为有几个页面请求了很多的数据,页面中还用到了一些定时器。
首先尝试通过chrome的performance和memory来查看内存和性能的变化,但是想要在页面卡死的时候进行内存分析比较难,往往这个时候chrome-devtool也会卡死,只有一次比较幸运,记录下了页面卡死的同时javascript占用内存同时飙升。
尝试了很多次之后,总是记录不了卡死同时的内存状况,我只好放弃了这个方法。既然是内存的问题,我就把所有使用定时器的地方都加上了销毁的操作,以避免内存的泄露。
改完之后我测试了一下,问题还是没能解决,同时测试又反馈打开了几个页面后,点击某个特定的按钮也会引起页面卡死。这下给我整懵了,说明还会有其他问题导致页面卡死,我决定把这个新的导致卡死的代码找出来然后一起修改。
新的卡死的症状是:打开几个页面,然后点击某个页面的一个按钮,会有一定几率导致卡死。这个按钮是弹出一个dialog对话框,这种操作应该是不会导致卡死的。并且有时候点击按钮能正常打开弹框并不会导致卡死。
我不断的来回点击页面,点击弹框,总是没有找到固定的规律。于是我决定重构整个页面,看看会不会是某些不规范的代码导致了这个问题。页面重构完之后,问题任然复现了,这让我有点怀疑人生。
我只好不断的操作页面,希望能发现问题复现的规律。期间我又发现了一个现象,在能正常打开dialog的时候,切换到其他页面有时也会导致卡死。我怀疑是这个弹框写的有问题,又再次查看了弹框的代码,但是代码并没有什么问题。
我开始上网搜,看看有没有什么解决方案,有些文章提到了页面缓存会导致卡死的问题,查看了代码之后,怀疑是顶部标签页的路由监听导致的问题,经过排查发现代码没有异常,使用了相同代码的其他项目也没有出现类似的问题,但是注释掉watch监听函数就没有再复现。
这下我彻底懵圈了,路由监听和页面级的弹框完全不搭嘎啊。我只好尝试把弹框里的内容注释掉,页面也没有再卡死了,我先抛开路由监听的问题,再次查看弹框的内容,弹框里都是form表单组件,只有一个下拉选框是封装成了组件,这个下拉选框组件在其他地方也有用到,也没有在其他地方引起卡死。
排查不出问题让我很烦躁,我只好不停的操作卡死的步骤,看看能不能总结出规律来。事实证明这只是徒劳无功。
无奈之下,我只好去重构下拉选框的组件,看看能不能发现点什么,果然问题是出现在下拉选框组件中,这个组件监听了路由的变化,在某个特定的页面重新请求了备选项列表,最终解决方案是把下拉选框组件中的路由监听去除解决了这个问题