渲染大组元素

时间:2014-08-12 09:19:49

标签: javascript jquery

如何使用" Stop Scripting Dialog"来呈现此内容。任何解决方案都可以理解。提前致谢

document.write("<ul>");

for(var i=0;i<1000000;i++){


    document.write("<li>");

    document.write("<div><input value='"+i+"'/></div>");

    document.write("</li>");


}

document.write("</ul>");

2 个答案:

答案 0 :(得分:5)

首先,我将假设这是一个理论上的讨论,因为没有页面设计应该考虑数百万个DOM元素。如果有人认为可能有这么多元素,那么应该制定一个不同的设计,一次显示数据的小窗口。

要绕过无响应的对话框,您必须将javascript进程分解为多个部分并分别执行每个部分,同时允许系统处理部分之间的其他事件。这通常是通过将工作分成块然后在setTimeout()上执行每个块来完成的。您可以在此处看到几个处理大型数组的示例:

Best way to iterate over an array without blocking the UI

但是,此测试存在许多问题,因为您还必须停止使用document.write(),因为一旦您让系统处理setTimeout()操作之间的其他事件,您就不能再使用document.write()在解析流中插入新元素,因为文档将完成解析。相反,您必须更改为在DOM中的适当位置动态插入DOM元素。

以下是一些代码:

function insertElements(num) {
    var totalCntr = 0;
    var chunkSize = 1000;
    var parent = document.getElementById("container");
    var progress = document.getElementById("progressCntr");

    function doChunk() {
        var chunkCntr = 0;
        var fragment = document.createDocumentFragment();
        while (chunkCntr < chunkSize && totalCntr < num) {
            var li = document.createElement("li");
            li.innerHTML = "<div><input value='" + totalCntr + "'/></div>";
            fragment.appendChild(li);
            ++totalCntr;
            ++chunkCntr;
        }
        parent.appendChild(fragment);
        progress.innerHTML = totalCntr;
        if (totalCntr < num) {
            setTimeout(doChunk, 0);
        }
    }    
    // start the whole thing
    doChunk();
}

insertElements(100000);

工作演示:http://jsfiddle.net/jfriend00/0vw82q5y/

目前设置为100,000个元素。如果您想尝试更高的值,欢迎(根据系统的内存限制)。

如果您降低chunkSize值,系统将在运行时更加响应用户输入。如果您增加chunksize值,整个端到端时间可能会更快。

如果每个块都可以是它自己的DOM树,那么它可以插入到一个单独的DOM操作中,那么这里的端到端时间会更快。如果您插入了所有<li>元素,那么这是不可能的。这里使用文档片段试图帮助解决这个问题,但最后,它仍然必须将每个<li>插入到它自己的文档中,这确实会减慢这个操作。

注意:将工作分解为块可能会降低整体端到端性能。我没有尝试优化此代码的性能,而是想说明这个概念。

答案 1 :(得分:0)

当javascript更新DOM对象时,浏览器必须再次呈现页面;在你的情况下,它将是100万次。这保证即使是最快的机器也会减速。

通过生成HTML尽可能多的时间来避免这种情况,但只要求浏览器渲染一次。

var list;
for (var i = 0; i < 1000000; i++) {
    list += "<li><div><input value='" + i + "'/></div></li>";
}
document.write("<ul>"+list+"</ul>");