-
Notifications
You must be signed in to change notification settings - Fork 0
/
LargeTask.html
139 lines (124 loc) · 3.03 KB
/
LargeTask.html
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Large Task</title>
<style>
.container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.ball-container {
position: relative;
width: 500px;
height: 100px;
}
.ball {
position: absolute;
width: 50px;
height: 50px;
border-radius: 50%;
background-color: red;
-webkit-animation: linear infinite;
-webkit-animation-name: run;
-webkit-animation-duration: 5s;
}
@keyframes run {
0% {
left: 0;
}
50% {
left: 100%;
}
100% {
left: 0;
}
}
</style>
</head>
<body>
<div class="container">
<p>點擊按鈕,會執行 1000 個任務</p>
<p id="log"></p>
<button>執行任務</button>
<div class="ball-container">
<div class="ball"></div>
</div>
</div>
<script>
const btn = document.querySelector("button");
const logText = document.querySelector("#log");
let completeTime = 0;
let completeCount = 0;
btn.onclick = function () {
// const startLog = Date.now();
for (let i = 0; i < 1000; i++) {
runTask(blockTask);
}
// logText.textContent = `執行了 ${Date.now() - startLog} ms`;
};
function blockTask() {
let run = true;
const startTime = Date.now();
while (run) {
const diff = Date.now() - startTime;
if (diff >= 5) {
completeCount++;
completeTime += diff;
run = false;
}
if (completeCount === 1000) {
logText.textContent = `執行了 ${completeTime} ms`;
}
}
}
/**
* 運行一個耗時任務
* 若要非同步運行,需返回 Promise
* 要盡快完成任務,且不要卡頓動畫
* 兼具瀏覽器相容
* @param {Function} task
*/
function runTask(task) {
run4(task);
}
function run1(task) {
// 直接執行 -> 阻塞
task();
}
function run2(task) {
// Micro Task -> 阻塞
return new Promise((resolve) => {
Promise.resolve().then(task).then(resolve);
});
}
function run3(task) {
// Marco Task -> 卡頓
return new Promise((resolve) => {
setTimeout(() => {
task();
resolve();
}, 0);
});
}
function run4(task) {
return new Promise((resolve) => {
_runTask(task, resolve);
});
}
function _runTask(task, callback) {
const start = Date.now();
requestAnimationFrame(() => {
if (Date.now() - start < 16.6) {
task();
callback();
} else {
_runTask(task, callback);
}
});
}
</script>
</body>
</html>