-
Notifications
You must be signed in to change notification settings - Fork 95
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
105 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
101 changes: 101 additions & 0 deletions
101
docs/front-end-basic/performance/front-end-performance-jank-detect.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
--- | ||
title: 前端性能优化--用户卡顿检测 | ||
--- | ||
|
||
前面跟大家介绍过[前端性能卡顿的检测和监控](./front-end-performance-no-response-solution.md),其中提到了`requestAnimationFrame`心跳检测等方式来检测代码执行耗时,从而判断是否存在卡顿。 | ||
|
||
而实际上我们观察一些用户反馈,会发现这样检测的效果并不是很理想。 | ||
|
||
# 用户感觉的“卡” | ||
|
||
一般来说,我们会根据代码检测的任务耗时超过一定值判断为卡顿,比如超过 1s 的长任务。但实际上,这样的方法难以准确命中“用户侧卡顿”的场景,这是因为: | ||
|
||
- 超过 1s 的任务执行时,用户未必在进行页面操作,未感受到“卡顿” | ||
- 对用户来说,在浏览器中各个过程中的卡顿阈值是不一致的,比如: | ||
- 页面打开过程中,会习惯性地等待,此时卡顿阈值会稍微高一些 | ||
- 页面加载完成后,对各种功能的操作响应更敏感,希望能快速响应操作 | ||
|
||
因此,我们可以重新定义卡顿指标,可以将其分为两种: | ||
|
||
1. 技术侧卡顿(代码长任务)。 | ||
2. 用户侧卡顿(交互响应耗时)。 | ||
|
||
本文我们重点来探讨用户侧卡顿的检测。 | ||
|
||
## 用户侧卡顿 | ||
|
||
如果你有认真整理用户反馈,便会发现,对于大型应用比如在线表格/网页游戏等,相比于加载过程中偶尔一两秒的卡顿,更让他们难以接受的问题有频繁出现卡顿、某个操作卡顿耗时过长、某个较频繁的操作必现卡顿等。 | ||
|
||
那么,我们可以基于这些场景,重新定义用户侧卡顿的指标,满足以下场景均可认为产生了卡顿: | ||
|
||
| 问题 | 对应性能指标 | 指标定义 | 补充说明 | | ||
| ------------------------------------------ | ----------------------------------------- | ------------ | ----------------------------------------------------------------- | | ||
| 操作后响应不及时 | 用户交互(点击)后,rAF 响应耗时 > 1000ms | 交互卡顿 | 类似 INP(参考 https://web.dev/articles/inp),但滚动行为考虑在内 | | ||
| 操作(编辑/滚动)频繁出现卡顿 | 20s 内,交互响应卡顿次数 > 5 | 交互卡顿频率 | | | ||
| 某个操作卡顿耗时过长,长达 5s/10s 甚至更多 | - 交互响应卡顿耗时 > 5s | | ||
| - 交互响应卡顿耗时 > 10s | 交互长耗时卡顿 | | | ||
| 某个较频繁的操作必现卡顿 | 相同的卡顿埋点次数 > 5 | 同因交互卡顿 | | | ||
|
||
这里有一个难处理的地方:如何判断用户交互后产生了卡顿呢?因为我们可以拆分成以下情况: | ||
|
||
1. 用户交互后,同步执行长耗时任务产生卡顿。 | ||
2. 用户交互后,异步执行逻辑的时候产生卡顿。 | ||
|
||
### 1. 同步任务卡顿 | ||
|
||
我们可以在监听到用户交互时进行耗时计算: | ||
|
||
```javascript | ||
window.addEventListener("click", () => { | ||
const startTime = new Date().getTime(); | ||
requestAnimationFrame(() => { | ||
const duringTime = new Date().getTime() - startTime; | ||
// 交互后超过 1s 才响应 | ||
if (duringTime > 1000) { | ||
// 则判断为卡顿 | ||
} | ||
}, 0); | ||
}); | ||
``` | ||
|
||
### 2. 异步任务卡顿 | ||
|
||
对于异步任务,由于卡顿发生在用户交互后,难以通过代码直接发现。我们可以从另外一个角度分析,即当页面交互发生卡顿时,用户常常会在页面中进行操作,来确认页面是否无响应。因此,我们可以通过这样的代码判断: | ||
|
||
```javascript | ||
let clickCount = 0; | ||
let hasClick = false; | ||
window.addEventListener("click", () => { | ||
clickCount++; | ||
if (hasClick) return; | ||
hasClick = true; | ||
setTimeout(() => { | ||
// 卡顿过程中发生了连续点击操作 | ||
if (clickCount > 2) { | ||
// 则判断为卡顿 | ||
} | ||
// 清空数据 | ||
clickCount = 0; | ||
hasClick = false; | ||
}, 0); | ||
}); | ||
``` | ||
|
||
## 总卡顿指标设计 | ||
|
||
综上所述,我们会将以下情况作为一次卡顿的产生,并且做卡顿次数的上报: | ||
|
||
- 用户交互后,同步卡顿超过 1s | ||
- 检测到一次宏任务中,用户连续点击操作超过 5 次 | ||
|
||
同时,我们可以在特特定场景发生的时候,将数据以及日志同时进行上报,比如: | ||
|
||
- 20s 内产生卡顿次数 > 5 | ||
- 检测到某段代码执行超过 5s/10s | ||
- 检测到卡顿埋点中卡顿(超过 1s)的相同埋点多次产生(相同的卡顿埋点次数 > 5) | ||
|
||
通过这样的方式,我们可以判断用户是否产生了卡顿。但实际上要如何定位卡顿的位置呢,还是得通过日志和埋点进行,可以参考[《前端性能优化--卡顿的监控和定位》](./front-end-performance-no-response-solution.md)一文。 | ||
|
||
# 结束语 | ||
|
||
很多时候,我们开发在实现功能的时候,常常会从编程出发去思考问题,但实际上我们可以更贴近用户一些滴~ |