如何延迟DOM元素的渲染以防止无响应

时间:2014-08-12 13:53:30

标签: javascript dom browser

我从服务器获取大量人员(1000)作为API调用 根据数据,我必须为每个用户呈现“卡片”,其中包含他们的姓名,图片,年龄等。

但是当我这样做时,浏览器会暂停一段时间,直到所有卡片都被渲染出来。有没有办法告诉浏览器不必一次渲染所有内容,它可以逐个渲染,而不会自行崩溃?

2 个答案:

答案 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:你真的需要同时展示所有项目吗?您可以设置滚动视图,在向下滚动时填充吗?

接下来您可以使用RactiveJsReact来有效管理数据绑定。

答案 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个,即使在渲染完成后,事情也会变得缓慢且无响应,因为内存使用率非常高。