0%

requestIdleCallback

requestIdleCallback作用

在网页中,有许多耗时但是却又不能那么紧要的任务。它们和紧要的任务,比如对用户的输入作出及时响应的之类的任务,它们共享事件队列。如果两者发生冲突,用户体验会很糟糕。我们可以使用setTimout,对这些任务进行延迟处理。但是我们并不知道,setTimeout在执行回调时,是否是浏览器空闲的时候。

而requestIdleCallback就解决了这个痛点,requestIdleCallback会在帧结束时并且有空闲时间。或者用户不与网页交互时,执行回调。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="text" id="text" style="width: 700px" />
</body>
<script>
const datas = []
const text = document.getElementById('text')
let isReporting = false


function sleep (ms = 100) {
let sleepSwitch = true
let s = Date.now()
while (sleepSwitch) {
if (Date.now() - s > ms) {
sleepSwitch = false
}
}
}
function handleClick () {
datas.push({
date: Date.now()
})
// 监听用户响应的函数,需要花费150ms
sleep(150)
handleDataReport()
}


// ========================= 使用requestIdleCallback ==============================


function handleDataReport () {
if (isReporting) {
return
}
isReporting = true
requestIdleCallback(report)
}


function report (deadline) {
isReporting = false
while (deadline.timeRemaining() > 0 && datas.length > 0) {
get(datas.pop())
}
if (datas.length) {
handleDataReport()
}
}


// ========================= 使用requestIdleCallback结束 ==============================


function get(data) {
// 数据上报的函数,需要话费20ms
sleep(20)
console.log(`~~~ 数据上报 ~~~: ${data.date}`)
}


text.oninput = handleClick
</script>
</html>

参考资料:https://juejin.cn/post/6844904081463443463