渲染
一次性渲染大量数据不卡顿
<body>
<ul id="list"></ul>
<script>
function render() {
const FRAME_TIME = 1000 / 60; // 定义每帧的时长
const TOTAL_ITEMS = 100000; // 总条数
const ITEMS_PER_RENDER = 20; // 每次渲染20条
const RENDER_COUNT = TOTAL_ITEMS / ITEMS_PER_RENDER;
const list = document.getElementById('list');
let renderedCount = 0;
function renderItem(deadline) {
if (deadline ? deadline.timeRemaining() > 0 : true) {
// 1. 使用文档碎片优化一次插入优化性能
const fragment = document.createDocumentFragment();
for (let i = 0; i < ITEMS_PER_RENDER; i++) {
const item = document.createElement('li');
item.innerText = Math.floor(Math.random() * TOTAL_ITEMS);
fragment.appendChild(item);
}
list.appendChild(fragment);
renderedCount += 1;
}
loop();
}
function loop() {
// 使用 requestIdleCallback 或者 requestAnimationFrame 函数循环渲染 li 元素,避免卡顿
if (renderedCount < RENDER_COUNT) {
// 2. 兼容性处理,使用 requestIdleCallback 或 requestAnimationFrame
if ('requestIdleCallback' in window) {
window.requestIdleCallback(renderItem);
} else {
scheduleAnimationTask(renderItem);
}
}
}
function run() {
if ('requestIdleCallback' in window) {
window.requestIdleCallback(renderItem);
} else {
scheduleAnimationTask(renderItem);
}
}
function scheduleAnimationTask(callback) {
let startTime = Date.now();
requestAnimationFrame(() => {
if (Date.now() - startTime < FRAME_TIME) {
callback();
} else {
scheduleAnimationTask(callback);
}
});
}
run();
}
render()
</script>
</body>虚拟列表实现
Last updated