渲染大组元素

Tuh*_*hin 1 javascript jquery

如何使用"停止脚本对话框"进行渲染.任何解决方案都可以理解.提前致谢

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>");
Run Code Online (Sandbox Code Playgroud)

jfr*_*d00 5

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

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

在不阻止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);
Run Code Online (Sandbox Code Playgroud)

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

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

如果您减小了chunkSize值,系统将在响应用户输入时响应.如果增加chunksize值,整个端到端时间可能会更快.

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

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