介绍
一次性渲染多条数据时出现的卡顿现象
# 🎏 使用场景
假设渲染三十万条数据, 如果同时执行,那么就会出现卡顿的现象, 所以这里需要分批渲染,约定好下一步什么时候执行,每次执行多少数据
思路
分时函数
何时启动下一步执行
每一步的执行量
因为浏览器每16.6毫秒左右都有一个渲染帧,可以利用每个渲染帧的空余时间来渲染
function performTasks(tasks) {
// 这里可以传入数组, 要渲染的数据
if (tasks == null || tasks.length == 0) return;
let index = 0; //记录渲染到第几个位置
function _run() {
requestIdleCallback((idle) => {
//每一步渲染帧空闲的时候执行
while (index < tasks.length && idle.timeRemaining() > 0) {
// 如果还有数据,并且这一渲染帧还有剩余时间的情况下继续 从下标位置开始渲染
tasks[index++]();
}
if (index < tasks.length) _run(); //如果还有数据,继续执行
});
}
_run();
}
以上有些浏览器不支持requestIdleCallback的api, 所以我们改造一下
让我们自己去决定什么时候下一步什么时候开始
function performTasks(tasks, dcheduler) {
// 这里可以传入数组, 要渲染的数据
if (tasks == null || tasks.length == 0) return;
let index = 0; //记录渲染到第几个位置
function _run() {
dcheduler((isGoOn) => {
while (index < tasks.length && isGoOn()) {
// 如果还有数据,并且isGoOn()返回true,继续执行
tasks[index++]();
}
if (index < tasks.length) _run(); //如果还有数据,继续执行
});
}
_run();
}
const scheduler = (chunk) => {
//定义一个调度器
let count = 0; // 定义每次要渲染的数量
setTimeout(() => {
// 定义一秒启动一次
chunk(() => {
return count < 10; //约定渲染的数量, 每次渲染都是十条十条
}); //执行函数 并传入约定 渲染的数量的函数
count++;
}, 1000);
};
performTasks(tasks, scheduler); //调用函数 传入要渲染的数据和 调度器, 调度器
// 同时,这个函数也是通用性的, 也可以继续使用requestIdleCallback
const scheduler = (chunk) => {
//定义一个调度器
chunk(
requestIdleCallback((deadline) => {
return deadline.timeRemaining() > 0
})
); //执行函数 并传入约定 渲染的数量的函数
};
