背景
上周接到一个性能问题的线上反馈:“浙江客户xxx报表展示超过20秒,小明看了相关接口响应都在2秒内,希望我协助排查。”
听完这个简短的描述我猜测可能是客户机房网络问题,为什么这么说呢,从描述中我提取到这么几个关键信息“个例,不是所有客户”、“后台响应很快”,给我的感觉好像是机房出口带宽满了,当然这只是猜测,需要拿出具体的证据。
初步排查
“信任但需要确认”,虽然我从研发口中得知后台响应很快,但是为了查问题我还是把相关账号要过来自己点了点,也看了后台的access log的确不慢,通过浏览器的Network -> Timing奇怪的发现,有个提示会停留20s左右“CAUTION:request is not finished yet!(注意:请求尚未完成)”,之后才会展示各项指标耗时,但是耗时都不高。
这个表象似乎和我猜测机房出口带宽满的想法不谋而合,接下来就是剥茧抽丝,证实客户机房网络的确有问题,提供证据让实施反馈客户,客户再去问候信息管理部,信息管理部再去问候运营商(和toG的客户打交道千万要谨慎,往往都会惊动一个链条上的人)。
由于我不是专业网工,对于网络问题也只能凭借自己的二把刀经验来做一些诊断,如果有不对的地方,请大家一定要指正。
ping -n 50 xxx.com
我首先通过ping的方式来观察是否有丢包情况,结论是网络良好,没有任何丢包情况。
接下来我又通过Wireshark抓包分析,本机发出请求到收到响应的时间确实在2s之内,这样看来报表展示慢和网络似乎是没关系,还需要继续挖掘原因。
强烈推荐大家学习Wireshark,对于网络学习、问题排查真的是一把利剑。
怀疑一切
之前提出的疑点偏后端领域,现在排查一圈下来矛头指向了前端,那就接着挖。
我看了报表页面内的js代码,逻辑很简单,就是ajax查询数据然后调用前端框架的setData方法,到底是哪段js代码把整个页面渲染给拖慢了呢。
我甚至怀疑是不是触发了jquery框架的某个bug,为了证实这一点我将请求数据那段从jquery切到了最原始的XMLHttpRequest,依然很慢。
要是浏览器能记录这个页面渲染过程中发生了什么,每个阶段的耗时分布,那排查问题就方便多了,我想到了曾经用过的skywalking、jaegertracing这类链路追踪工具,排查后端性能问题很是方便。
最终借助搜索引擎找到了chrome的Performance,请搜索“chrome 前端性能优化工具”详细了解,真是好用,前后不到两分钟就找到了性能瓶颈点。
开始采集
F12-Performance->点击开始记录->刷新页面->等待页面渲染完成->点击停止记录
查看调用树
点击上图红框部分的Call Tree查看调用链路和每个节点的耗时,重点关注耗时占比较大的调用栈,如下图所示拖慢整个页面渲染的元凶是jCommon.js中的两个设置表格样式的函数。
这两个函数的触发时机在jCommon.js的$(function(){}中,属于通用逻辑,之所以其他客户没有受到影响,是因为其他客户对于表格的个性化设置没有开启,所以没有执行,我大体看了一下逻辑内部有太多的递归+循环调用,遇到复杂(行列合并、嵌套)而且数据量大的表格就是一种噩梦,更细节的就不多说了,不是本篇的重点。
解决办法
“让专业的人干专业的事”,因为前端我并不擅长,所以我将这个问题的根治任务抛给了前端同学,这块代码是必须要优化的,太损耗性能。同时对于当下的问题我也给出了建议,在当前报表页面暂时剔除这段逻辑,初衷是用来提升用户体验,现在看来已经严重影响到可用性。
总结
透过一个简单的性能问题,聊聊笔者排查的思路和中途用到一些工具,最终借助浏览器的性能分析工具发现前端问题代码,对于陌生的领域一款良好的工具可以降低排查的门槛,事半功倍。
推荐阅读
https://developer.chrome.com/docs/devtools/evaluate-performance/reference/
https://docs.microsoft.com/zh-cn/microsoft-edge/devtools-guide-chromium/evaluate-performance/