我从服务器获取大量人员(1000)作为API调用 根据数据,我必须为每个用户呈现“卡片”,其中包含他们的姓名,图片,年龄等。
但是当我这样做时,浏览器会暂停一段时间,直到所有卡片都被渲染出来。有没有办法告诉浏览器不必一次渲染所有内容,它可以逐个渲染,而不会自行崩溃?
答案 0 :(得分:1)
看看here
如果向DOM添加元素,则会重新绘制页面。如果你逐个添加100个元素,它将被重新绘制100次,而且速度很慢。创建一个容器,并在将项目附加到页面之前将项目添加到
。var container = $('<div>');
$.each(items, function (index, itm) {
var el = $('<div>');
el.attr('id', ID_PREFIX + index);
el.html(createHtml(itm));
container.append(el);
});
$('#list-container').append(container);
类似于上面的内容(使用jQuery,但你可以使用普通的JS)。
(当然createHtml
是一个实用程序函数,您可以定义该函数来获取项目的标记,items
是包含数据的数组)
那就是说,我同意上面的@Bergi:你真的需要同时展示所有项目吗?您可以设置滚动视图,在向下滚动时填充吗?
答案 1 :(得分:1)
这里有一些选择。正如其他人所提到的,最好的选择是根本不渲染:
使用“无限滚动”技术仅渲染您需要的内容。基本思路是删除屏幕外的DOM元素,并通过检查滚动位置添加屏幕上显示的元素。
使用其他用户驱动的分页机制。
除此之外,通过构建和设置innerHTML
或使用文档片段,您可以通过一次性渲染来获得更好的性能。但是,如果使用1000个元素,你的表现仍会很差。
此时,您可能需要批处理。这不会更快,但它会释放UI,以便在渲染时不会锁定内容。一个非常基本的批处理方法可能如下所示:
// things to render
var items = [...];
var index = 0;
var batchSize = 100;
// time between batches, in ms
var batchInterval = 100;
function renderBatch(batch) {
// rendering logic here
}
function nextBatch() {
var batch = items.slice(index, index + batchSize);
renderBatch(batch);
index += batchSize;
if (index < items.length - 1) {
// Render the next batch after a given interval
setTimeout(nextBatch, batchInterval);
}
}
// kick off
nextBatch();
值得注意的是,这是有限制的 - 渲染是一个瓶颈,但每个DOM元素也会影响客户端内存。使用1000个元素中的10个,即使在渲染完成后,事情也会变得缓慢且无响应,因为内存使用率非常高。