Chrome中的appendChild性能问题

时间:2014-01-08 16:27:59

标签: javascript google-chrome dom

我在使用javascript中的appendchild行的chrome速度问题。这似乎在firefox和chrome中运行良好,但Chrome并不是非常慢。我只想在按钮点击上添加一个元素。该页面已经有超过10,000个元素,但我不确定这是否是问题的一部分。

回顾我看过的事情。我查找了文档片段,并试图实现它,但得到了相同的结果。从我收集的内容来看,当您向dom添加大量元素时,文档碎片通常会提高性能,而不仅仅是一个。 (如果我在这个假设上错了,请随意纠正我)。我还在Chrome中运行了时间线,发现了"布局"正在加载11.91s并且似乎被卡在appendchild线上。我已经评论了下面的问题。

正如我之前提到的,我尝试过没有改进的文档片段,所以这是我的原始代码。

function addYr() { 
         divArray = document.getElementById('acct_sect').getElementsByTagName("div");
         divRow = document.createElement("div");
         divRow.id = "acct_row_" + (divArray.length);

         var yr  = document.createElement("input");
         yr.type= "text";
         yr.id= "yr_" + divArray.length;
         yr.name= "yr_" + divArray.length;
         yr.setAttribute("onkeydown", "TabNext(this,'down',2); return justNums(event);");
         yr.setAttribute("onkeyup", "TabNext(this,'up',2,this.form.fnd_)");
         yr.maxLength = 2;   
         yr.className = "c1";
         yr.setAttribute("onchange", "buildAccountMultiRow(this)");
         yr.value = "";

         divRow.appendChild(yr);


    //line that is taking a while
    document.getElementById('acct_sect').appendChild(divRow);
}

1 个答案:

答案 0 :(得分:1)

大量元素最有可能受到指责,但这里有一些尝试:

  • getElementsByTagName返回一个实时列表,每次更改时都必须更新。相反,试试这个:

    divArray = document.getElementById('acct_sect').children;
    
  • 如果您没有使用id属性,请删除它。

  • 如果您可以重新安排服务器上的某些代码,请尝试:

    yr.name = "yr[]";
    

    然后在服务器上,您将获得(例如在PHP中)$_POST['yr']作为包含值的数组。

  • 如果你可以同时完成上述两个项目,那么你会发现你甚至不再需要divArray,而且可以完全摆脱它,这应该可以节省很多时间。
  • 尝试更改处理事件的方式。不是为每个元素分配三个事件处理程序,而是为容器分配一个。

    var ac = document.getElementById('acct_sect');
    ac.onkeydown = function(e) {
        e = e || window.event;
        var t = e.srcElement || e.target;
        if( t.nodeName == "INPUT") {
            tabNext(t,'down',2);
            return justNums(e);
        }
    };
    ac.onkeyup = function(e) {
        e = e || window.event;
        var t = e.srcElement || e.target;
        if( t.nodeName == "INPUT") {
            tabNext(t,'up',2,t.form.fnd_);
        }
    };
    ac.onchange = function(e) {
        e = e || window.event;
        var t = e.srcElement || e.target;
        if( t.nodeName == "INPUT") {
            buildAccountMultiRow(t);
        }
    };