时间切片
时间切片的核心思想是:如果任务不能在50毫秒内执行完,那么为了不阻塞主线程,这个任务应该让出主线程的控制权,使浏览器可以处理其他任务。让出控制权意味着停止执行当前任务,让浏览器去执行其他任务,随后再回来继续执行没有执行完的任务。
所以时间切片的目的是不阻塞主线程,而实现目的的技术手段是将一个长任务拆分成很多个不超过50ms的小任务分散在宏任务队列中执行。
- 时间切片(Time Slicing) (opens new window)
- 时间切片编程 timeslice (opens new window)
- 「前端进阶」高性能渲染十万条数据(时间分片) (opens new window)
# setTimeout + Generator
function request() {
let result = [];
for (let i = 0; i < 100000; i++) {
result.push({
index: i,
text: ~~(Math.random() * 100000000),
});
}
return Promise.resolve(result);
}
let ul = document.querySelector("#app");
request().then((res) => {
function ts(gen) {
if (typeof gen === "function") gen = gen();
if (!gen || typeof gen.next !== "function") return;
return function next() {
const res = gen.next();
if (res.done) return;
requestAnimationFrame(next);
};
}
let total = res.length;
let once = 20;
let page = total / once;
let curIndex = 0;
ts(addDom(total))();
function* addDom(curTotal) {
while (curTotal > 0) {
let pageCount = Math.min(curTotal, once);
let fragement = document.createDocumentFragment();
for (let i = 0; i < pageCount; i++) {
let li = document.createElement("li");
li.innerText =
"index: " +
res[curIndex + i].index +
"; text: " +
res[curIndex + i].text;
fragement.appendChild(li);
}
ul.appendChild(fragement);
curIndex = curIndex + pageCount;
curTotal = curTotal - pageCount;
yield;
}
}
})
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
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
编辑 (opens new window)
上次更新: 2021/08/04, 18:53:40