使用ric处理繁重任务
<style>
* {
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
}
#box {
width: 400px;
height: 600px;
overflow-y: scroll;
}
</style>
</head>
<body>
<p style="color:red;">请点击按钮1和按钮2,分别滚动div,查看scroll的触发情况</p>
<br>
<br>
<button id="btn1">正常繁重计算开始</button>
<button id="btn2">ric繁重计算开始</button>
<div id="box">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequuntur, cum. Vero culpa sequi maxime harum
voluptatibus, nostrum deleniti error optio tempore quaerat quos hic placeat rem ipsa velit odit aperiam soluta
sunt repellendus. Doloribus eum nesciunt sed asperiores corrupti deleniti libero molestias, enim repellendus?
Quaerat omnis amet maxime odit cum quo ea porro. Adipisci quos perspiciatis earum iure accusamus a, reiciendis
repellendus. Perferendis nulla, placeat fugiat nihil quidem ipsa nesciunt quaerat voluptatibus doloremque ea
ipsam maiores natus eveniet facere perspiciatis quae! Aliquid totam maiores culpa aperiam nemo, quo possimus,
fugiat officia illo nihil ratione reprehenderit cum enim nostrum. Dicta molestias veniam rem deleniti. Nulla quo
quas quidem consectetur, ea, dolore tempora officia quos, repellendus perferendis voluptate cum. Voluptates quod
quaerat quae at velit reiciendis voluptate id maxime laborum veniam mollitia illo nulla inventore ab eveniet,
modi laboriosam tenetur enim maiores ea! Deleniti magnam harum reprehenderit sunt quas. Nobis repellendus
cupiditate unde blanditiis. Perspiciatis, totam odit. Aliquid enim libero sint cum vel praesentium debitis!
Distinctio iure itaque rerum expedita, eveniet vel rem eius minus animi doloremque? Rem ratione architecto autem
magnam eius dolorem aspernatur ex, corrupti, minus consectetur aut ad officia. Rerum reiciendis debitis soluta?
Fugit, incidunt corrupti veniam dolorem error nam cumque excepturi similique pariatur.
</div>
<script>
// 假设一个繁重任务被拆分成4个小任务来执行
function task1() {
console.log("🚀 ~ task1 ~ ");
let sum = 0;
const max = 400000000;
for (let i = 0; i < max; i++) {
sum += Math.sqrt(i);
}
}
function task2() {
console.log("🚀 ~ task2 ~ ");
let sum = 0;
const max = 400000000;
for (let i = 0; i < max; i++) {
sum += Math.sqrt(i);
}
}
function task3() {
console.log("🚀 ~ task3 ~ ");
let sum = 0;
const max = 400000000;
for (let i = 0; i < max; i++) {
sum += Math.sqrt(i);
}
}
function task4() {
console.log("🚀 ~ task4 ~ ");
let sum = 0;
const max = 400000000;
for (let i = 0; i < max; i++) {
sum += Math.sqrt(i);
}
}
/*
长时间占用主线程,阻塞交互
期间触发滚动后会被卡顿,知道任务执行完成后会触发一次scroll
*/
btn1.onclick = () => {
console.time('heavyTask');
const taskQueue = [task1, task2, task3, task4];
while (taskQueue.length > 0) {
taskQueue.shift()();
}
console.timeEnd('heavyTask');
}
/*
利用空闲时间且尽量减少主线程的占用时长
在执行任务中间有更多机会去处理其它任务
而且执行完所有任务的用时相比上面更短
减少阻塞经量让交互更加流畅
*/
btn2.onclick = () => {
const taskQueue = [task1, task2, task3, task4];
requestIdleCallback(function handleTask(deadline) {
// console.log('剩余时间:', deadline.timeRemaining());
const start = performance.now();
while (taskQueue.length > 0 && deadline.timeRemaining() > 10) {
taskQueue.shift()();
}
taskQueue.length ? requestIdleCallback(handleTask) : console.log('heavyTaks:', performance.now() - start);
});
}
// 点击按钮后去滚动试试
box.onscroll = () => {
console.log('scroll');
}
</script>
总结
使用ric把繁重任务分割处理,减少了主线程阻塞,并且在低优先级的情况下去处理,可以优化用户的交互体验。