卡顿率突增时,最快定位路径是:先比对时间窗与发布记录,再沿“客户端渲染→网络请求→服务端响应”逐层下钻,优先排查JS异常与慢接口。
卡顿率突增怎么排查:先锁定时间窗口和版本
卡顿率突增听起来吓人,但绝大多数情况下不是架构崩了,而是某一次改动或某一类用户特征在短时间内集中爆发,第一步永远不是翻代码,而是把卡顿率的趋势图和发布记录放在同一张图里看。
具体操作路径:
- 打开APM平台的“卡顿率”看板,切换为分钟级粒度,把突增发生的时间精确到5分钟以内。
- 调出最近48小时的发布记录、配置变更记录、后端服务发版日志。
- 在时间轴上做交叉比对:如果卡顿率在某个时间点出现“台阶式上升”,而不是缓慢爬坡,那么八成和这个时间点的发布有关。
- 如果找不到对应发布,再看网络层,比如运营商线路割接、CDN节点异常、DNS解析超时。
常见的情况是:前端改了一个图片懒加载逻辑,结果导致长列表页面在低端机上同步解码大量图片;后端加了一个防刷拦截,所有请求被排队等待,这两类问题在时间窗口上都会表现为突增,但处理方式完全不同。
如何用版本对比确认是“新代码还是新流量”
如果发布记录实在对不上,就用“A/B对比”的思路定位。
- 把突增时段内的用户会话拆开,按客户端版本分组。
- 对比老版本与新版卡顿率:老版本也涨,说明问题在公共环境;老版本不涨,问题就在新版逻辑。
- 再按地域维度切一刀:如果只有某个省份的卡顿率涨,优先查运营商线路或边缘节点。
这个操作不需要写什么高级脚本,多数APM平台的自定义分组功能都能直接做,重点在于先否认“所有用户都卡”,再缩小到特征用户群。
页面卡顿率突然升高的常见原因与分层定位法
页面卡顿率突然升高,原因不会只有一个,行业共识认为,真正值得优先投入时间排查的,永远是“影响面最大且最容易被改动触发”的那一层,这里给出一套分层定位法,从三个层面逐个排除。
客户端层:渲染阻塞和JS长任务
卡顿的直接表现是用户操作后响应不及时,本质上是主线程被占满,用性能分析工具抓一段现场数据,重点看Long Task和FCP/LCP。
- 如果Long Task集中在脚本执行阶段,优先看首屏 JS 是否加载了过重的第三方库。
- 如果FCP正常但LCP很差,说明最大元素渲染被晚到的图片或字体文件拖住了。
- 如果滚动列表触发掉帧,检查是否在列表渲染中用了同步的样式计算或大型组件频繁重渲染。
现场不好抓?那就用采样工具:在性能条目里记录 firstInputDelay 和 longtask 事件,缓存最近100条,等卡顿突增时直接拉取最近样本,这类样本比事后推测更有说服力。
网络层:请求排队和资源耗时
页面卡顿不等于CPU忙,也可能是网络请求把关键资源堵住了,这里要区分“加载慢”和“渲染卡”,前者是资源到达时间晚,后者是到达后处理不过来。
- 看瀑布图里是否有“长尾请求”超过2秒,这类请求会阻塞后续依赖它的脚本执行。
- 看请求并发度,很多低端机在HTTP/1.1时代会对同一域名限制并发数,若瞬时请求太多,排队时间直接淹没渲染时间。
- 走WebSocket的页面还要额外关注心跳重连次数,频繁重连会导致主线程频繁解析握手数据。
一个典型案例:突增时段内,所有静态资源都从同一个CDN域名分发,恰好该域名发生了节点故障,导致回源率上升,此时卡顿率曲线和CDN回源率曲线几乎重合。
服务端层:慢接口拖垮前端渲染
前端卡顿率突增,并不意味着问题一定在前端,接口响应变慢会让页面在等待数据时保持挂起状态,表现上同样是“卡”。
- 在APM里筛选出突增时段的TOP慢接口,看P95响应时间是否环比翻倍。
- 对比接口调用量和异常数,如果调用量没变但P95涨,优先查数据库慢查询、锁竞争、缓存失效。
- 看服务端GC频率和内存回收耗时,老年代频繁GC会直接表现为接口周期性延迟。
行业共识是:错误率与卡顿率联动时,问题大概率在服务端;错误率没变而卡顿率涨,问题大概率在渲染层,这条规律能帮你快速决定要不要把后端叫起来。
从监控告警到根因:卡顿率突增的实操定位路径
说完了原理,给一条能直接照着点按钮的路径,这条路径不依赖具体监控平台,但每个步骤都对应可验证的信息。
第一步:确认指标口径,别被假卡顿骗了
先回答“这个卡顿率是怎么算的”,不同平台计算方法不同:
- 以“FID > 500ms”为样本还是“Long Task > 50ms”为样本?
- 分母是“有交互的页面”还是“所有页面访问量”?
- 统计口径是否包含无声卡、后台标签页?
口径不同,数值可能差出两倍以上,很多所谓的突增其实是改了采样覆盖率或过滤规则,先把口径确认清楚再往下查。
第二步:抓取现场样本,而不是看汇总曲线
汇总曲线只能告诉你“发生了什么时刻”,样本才能告诉你“哪个用户、哪个页面、哪个操作”,快速抓包思路如下:
- 在监控后台开启“会话级采样”,把卡顿阈值调到当前P75水平,这样能抓到正在卡顿的会话。
- 给这些会话打上标签,
session:kadun-spike-2026,方便后续分析。 - 导出每个会话的trace,重点看
longtask的事件堆栈和耗时最长的JS函数。
如果平台不支持抽样,可以直接在埋点代码里加一个条件:当 performance.getEntriesByType('longtask') 存在且执行时间超过200ms时,主动上报一条原始堆栈。
第三步:按“渲染资源-请求-代码逻辑”顺序检查
拿到样本后不要乱翻,顺序很重要。
- 先看页面渲染资源的加载顺序,图片是否未显式指定宽高?CSS是否在渲染链路上阻塞?字体是否以
display=swap加载? - 再看关键接口的耗时分布,如果接口P95是3秒,那么卡顿的源头就有一半在接口。
- 最后才看代码逻辑,用性能面板的“Call Tree”定位到具体函数,再打开源码对应行。
这套顺序能把多数问题控制在10分钟之内锁定范围,真正需要改代码的情况反而不多,多数是资源策略或缓存配置问题。
第四步:临时止血与根治方案要分开
- 临时止血:关闭导致卡顿的灰度开关、回退上一版本、CDN切备份源、在服务端给慢接口加短时缓存。
- 根治方案:修改图片裁剪参数、懒加载阈值调低、将大计算迁移到Web Worker、接口拆分或将轮询改为长连接。
不要跳步,很多团队直接跳到“优化代码”,结果做了两天发现是CDN源站带宽打满,得不偿失,先止血,再分析,最后改代码,这个节奏最稳。
卡顿率与崩溃率的区别:别把两者混为一谈
卡顿率突增时,运维群里的第一个问题往往是“是不是崩溃了?”这很正常,但两者必须分开对待,崩溃是进程没了,卡顿是进程活着但响应慢,它们反映的是两类问题:
| 维度 | 卡顿率 | 崩溃率 |
|---|---|---|
| 用户感受 | 点一下半天才有反应 | 页面闪退或直接白屏 |
| 主要成因 | 主线程阻塞、长任务、慢接口 | 内存溢出、未捕获异常、原生代码错误 |
| 监控重点 | Long Task、FID、LCP、接口P95 | 崩溃堆栈、OOM、ANR、内存峰值 |
| 处理优先级 | 先看发布时间窗和资源加载 | 先看异常堆栈和受影响版本 |
如果你把卡顿当崩溃排查,会浪费大量时间在堆栈分析上,而忽略掉网络层和资源层,反过来,如果把崩溃当卡顿处理,你会去调主线程,但页面其实已经无响应了。两者需要完全不同的埋点和告警策略。
如何避免卡顿率和崩溃率告警互相干扰
简单做法是设置独立告警规则:
- 卡顿率告警只看“连续5分钟超过基准线P95”的会话数。
- 崩溃率告警只看“启动即崩溃”和“后台进程崩溃”的比例。
- 两者同时告警时,优先把后端服务健康状态拉出来后端故障往往会让前端既卡又崩。
这个区分对售后和客服尤其重要,因为用户描述“卡死了”可能指的是转圈,也可能指的是闪退,定位前先确认问题类别,能节省一半沟通成本。
卡顿率突增时快速定位的常见问题
卡顿率突增但错误率没变,是什么问题?
大概率是渲染资源或主线程执行阻塞,错误率不变意味着服务端接口没有报错,网络请求也正常,此时把焦点放在前端性能条目上,尤其关注长任务的数量和耗时,很多时候只是因为某张图片太大了,解码占满了主线程,但业务逻辑并没有崩溃。
如何区分卡顿率突变是低端机还是高端机造成的?
按设备性能分组看卡顿率,如果低端机卡顿率远高于高端机,说明是本地渲染压力问题,需要减少主线程工作量;如果高端机也涨,说明问题可能与业务逻辑或网络请求有关,设备性能无法缓解,这类分组在大多数移动端APM工具里是内置维度,直接切换即可,有个比较实用的做法是,看卡顿率曲线与“内存占用大于XXMB”的用户占比曲线是否同步变化,如果同步,则优先做内存优化。
没有APM工具,小程序或纯前端项目怎么做快速定位?
可以直接用浏览器和移动端的性能API自己搭建一套微型监控:用 PerformanceObserver 订阅 longtask 和 layout-shift,把超过阈值的事件拼接成一条堆栈信息,通过已有的请求通道上报到后端,控制台里用 performance.timing 也能粗略看出问题在DNS、TCP还是DOM解析阶段,如果要和卡顿率指标对齐,按照“长任务次数除以页面交互次数”来算即可,这套成本很低,但只能覆盖前端部分,服务端和网络层需要另做埋点,最终卡顿率的稳定口径还是推荐走商用或开源的完整APM方案。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/715825.html





