“这个页面最近很卡。”
收到这种反馈时,很容易先问网速怎么样。用户说别的 App 都正常,于是再去看服务端监控,接口耗时也不高。几轮对话下来,大家手里都有一条正常数据,问题却还在。
卡是用户对整个过程的描述。它可能是按钮点了没反馈,也可能是请求在等待,或者数据已经回来,页面还没有显示出来。
要开始排查,得先把“卡”变成一个能找到起止点的事件。
先让用户描述屏幕发生了什么
比起直接问延迟和丢包,更容易回答的问题是:点击后按钮有没有变化?文字出来了但图片没有吗?等待时还能滚动页面吗?最后是成功、报错,还是用户主动退出了?
这些问题能初步区分几种现象。
整个界面不能响应,值得查设备和主线程;页面能滚动,只有某个区域一直加载,值得追踪对应任务。它们仍然只是线索,不是看到一个现象就立刻确定原因。
一段包含操作前后的录屏通常很有帮助。只有加载动画的截图,看不到用户什么时候点击,也看不出到底等了多久。
先找到明确动作,例如“点击订单详情,到订单内容可读”,后面的时间测量才有共同口径。
一次点击,可以慢在好几个地方
下面是一条简化的过程。真实系统可能并行执行,也可能使用已有连接或缓存,不一定每次都完整经过所有阶段。
| 阶段 | 可以调查什么 |
|---|---|
| 点击到请求准备完成 | 页面处理、读取本地数据、任务排队 |
| 解析和连接 | DNS、连接建立、安全握手及连接复用 |
| 请求发出到首段响应 | 网络往返、服务端排队和处理 |
| 后续数据接收 | 数据大小、实际传输速度和重传 |
| 数据到达后显示 | 解析、图片解码、布局与渲染 |
浏览器的 Resource Timing 就采用阶段化的方式记录资源加载,包括解析、连接以及请求和响应的时间点。原生应用可以借鉴这种拆分思路,但具体能获得哪些时间点,要看平台和网络库。W3C Resource Timing
有一个特别容易算错的地方:从发出请求到收到首字节,中间包含网络传输和服务端等待,不能直接叫“服务器处理时间”。想拆出服务端内部耗时,需要服务端记录配合。
缓存命中或复用连接时,某些阶段可能没有重新发生;缺失或受限制的测量值,也不能一律当成耗时为零。
先对齐同一次操作,再比较日志
客户端说请求等了 8 秒,服务端说只处理了 200ms,两边可能都对。
请求在发送前排队、连接建立很慢,或者响应在回程遇到问题,都能产生这个差距。另一种更简单的可能是:两边看的根本不是同一次请求。
给一次操作和相关请求保留可关联的标识,往往比多打几百行日志更有用。一次页面加载如果触发多条请求,也要知道哪一条阻碍了用户看到结果。
本地耗时适合用单调时钟记录,避免系统时间调整影响结果。跨设备、跨服务比较时间,还需要考虑时钟差异,不能拿两个未经对齐的时间戳直接相减。
先把同一件事对上,再去讨论那几秒去了哪里。
一次对照实验,只改一个值得怀疑的条件
假设问题是“打开详情页很慢”。可以先在相同设备、账号和数据上,分别测试正常网络与受控高延迟,保留各阶段耗时。
如果增加延迟后等待明显增加,且页面依次发起多轮请求,可以继续调查串行依赖。若网络恢复正常后仍然在数据显示阶段卡住,就应该看解析与渲染,而不是继续提高丢包率。
首次打开与再次打开也要分开。缓存、连接复用和预加载可能让第二次快很多。把第一次当旧版本结果、第二次当新版本结果,会轻易得出错误的优化结论。
设备发热、后台负载和测试数据大小也值得记录。一次实验里又换手机、又换网络、又清缓存,结果即使改善了,也很难知道哪个变化有用。
受控弱网的作用是检验猜测:让某个条件可重复地变化,观察对应阶段是否跟着变。它不保证一次测试就找到全部原因。
平均只要 200ms,为什么用户还在抱怨?
看一个假设例子:100 次操作里,99 次各花 100ms,另一次花了 10 秒。平均耗时是 199ms,看着不算慢,那位等了 10 秒的用户却不会认同。
平均值适合描述整体水平,但少量很慢的操作可能被掩盖。可以同时看超过某个业务阈值的比例,以及慢操作的具体记录。
p95 也经常被用来观察较慢的一端。通俗地说,把耗时从小到大排列,它对应大约 95% 的样本耗时不超过的位置;具体计算方式可能有插值差异。
但 p95 也不是最慢情况。在上面这个例子里,它可能仍然是 100ms,完全看不到那一次 10 秒的等待。对关键业务,不能只盯一个百分位数字。
比较数据前,还要问样本包含哪些操作、有没有漏掉失败和超时。只统计成功请求,最差的体验可能已经被排除在报表外了。样本太少、统计时间段不同,百分位也会不稳定。
弱网报告能回答到哪一步?
一份网络模拟报告可以说明配置了什么条件、实际做出了哪些丢包和延迟决策,以及记录到的吞吐和运行事件。
它不天然知道用户何时点击、订单何时创建,或者客户端解码图片用了多久。HTTPS 内容加密时,仅靠数据包更不能直接读出业务接口返回的状态。
报告里的“应用延迟”也要看定义。如果它表示模拟器对包施加的等待,就不能把它当成页面响应时间。网络指标与业务指标需要通过明确的时间点和测试步骤关联。
有人手动标记,也有人通过测试脚本和客户端记录关联。选哪种方式取决于现有工具能力,不能因为报告里有时间线,就假定所有业务动作都被自动记录了。
让下一次反馈少一点来回追问
不需要用户提供一套性能分析报告。先收集可执行的操作步骤、发生时间、应用版本、设备与网络类型,再附上经过必要遮挡的录屏,就已经能减少很多猜测。
团队补充同一次操作的阶段耗时和错误记录,再用受控环境尝试重现。如果只能在特定网络出现,也应该保留这个范围,而不是因为办公室复现不了就判断不存在。
修复后要回到原来的用户过程验证。接口快了,不代表页面可读时间一定改善;平均值下降了,也要看看超时和特别慢的操作有没有一起减少。
最终报告可以很具体:慢在连接阶段,还是慢在数据显示阶段;改动后哪个时间缩短了,在哪些条件下仍然有问题。对于证据不足的部分,就保留为待验证的猜测。
下次用户再说“很卡”,先从他点击的那个按钮开始,把等待拆开。能说清楚慢发生在哪里,才知道接下来该调整网络、检查服务端,还是回到客户端看看页面为什么迟迟没有动。
2623



被折叠的 条评论
为什么被折叠?



