2014-01-08 18 views
1

我在使用javascript中的appendchild行的chrome中遇到了速度問題。這似乎在Firefox和Chrome中運行良好,但不是Chrome非常慢。我只是試圖在點擊按鈕上添加一個元素。該頁面已經有超過10,000個元素,但我不確定這是否是問題的一部分。Chrome中的appendChild性能問題

只爲了解我看過的東西。我查閱了文檔片段,並試圖實現它,但得到了相同的結果。從我所收集的內容來看,documentfragment通常會在您將很多元素添加到dom時提高性能,而不僅僅是一個。 (如果我在這個假設上錯了,請隨時糾正我)。我也在Chrome中運行時間線,發現「佈局」需要11.91秒才能加載,並且似乎陷入了appendchild行。我在下面評論了這條線。

正如我前面提到的,我已經嘗試過沒有改進的documentfragment,所以這是我的原始代碼。

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

它可能會更快,如果你沒有設置事件處理程序的字符串屬性(必須evalled),但作爲標準功能(即'yr.onkeydown =函數(){.. .'),對所有元素使用相同的函數會更好。 –

+0

@dystoy,感謝您的評論。我會試試這個。這可能只是我笨拙的閱讀理解,但當你說「對所有元素使用相同的功能」時,你是什麼意思。 – chuckw87

+0

我的意思是你的字符串是一樣的。因此,只需在循環外定義一個函數'function myFunction(){TabNext(this,'down',2);返回justNums(event)}'並且在追加時執行'yr.onkeydown = myFunction'。 –

回答

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); 
        } 
    };