使用DocumentFragments或innerHTML取代復(fù)雜的元素注入

2016-03-28 14:57:08來(lái)源:imooc作者:

DOM操作在瀏覽器上是要付稅的。盡管性能提升是在瀏覽器,DOM很慢,如果你沒(méi)有注意到,你可能會(huì)察覺(jué)瀏覽器運(yùn)行非常的慢。這就是為什么減少創(chuàng)建集中的DOM節(jié)點(diǎn)以及快速注入是那么的重要了。

DOM操作在瀏覽器上是要付稅的。盡管性能提升是在瀏覽器,DOM很慢,如果你沒(méi)有注意到,你可能會(huì)察覺(jué)瀏覽器運(yùn)行非常的慢。這就是為什么減少創(chuàng)建集中的DOM節(jié)點(diǎn)以及快速注入是那么的重要了。

現(xiàn)在假設(shè)我們頁(yè)面中有一個(gè)<ul>元素,調(diào)用AJAX獲取JSON列表,然后使用JavaScript更新元素內(nèi)容。通常,程序員會(huì)這么寫:

Javascript代碼

var list = document.querySelector(‘ul‘); 
ajaxResult.items.forEach(function(item) { 
    // 創(chuàng)建<li>元素 
    var li = document.createElement(‘li‘); 
    li.innerHTML = item.text; 

    // <li>元素常規(guī)操作,例如添加class,更改屬性attribute,添加事件監(jiān)聽(tīng)等 

    // 迅速將<li>元素注入父級(jí)<ul>中 
    list.apppendChild(li); 
}); 

上面的代碼其實(shí)是一個(gè)錯(cuò)誤的寫法,將<ul>元素帶著對(duì)每一個(gè)列表的DOM操作一起移植是非常慢的。如果你真的想要 使用document.createElement,并且將對(duì)象當(dāng)做節(jié)點(diǎn)來(lái)處理,那么考慮到性能問(wèn)題,你應(yīng)該使用DocumentFragement。

DocumentFragement 是一組子節(jié)點(diǎn)的“虛擬存儲(chǔ)”,并且它沒(méi)有父標(biāo)簽。在我們的例子中,將DocumentFragement想象成看不見(jiàn)的<ul>元素,在 DOM外,一直保管著你的子節(jié)點(diǎn),直到他們被注入DOM中。那么,原來(lái)的代碼就可以用DocumentFragment優(yōu)化一下:

Javascript代碼

var frag = document.createDocumentFragment(); 

ajaxResult.items.forEach(function(item) { 
    // 創(chuàng)建<li>元素 
    var li = document.createElement(‘li‘); 
    li.innerHTML = item.text; 

    // <li>元素常規(guī)操作 
    // 例如添加class,更改屬性attribute,添加事件監(jiān)聽(tīng),添加子節(jié)點(diǎn)等 

    // 將<li>元素添加到碎片中 
    frag.appendChild(li); 
}); 

// 最后將所有的列表對(duì)象通過(guò)DocumentFragment集中注入DOM 

document.querySelector(‘ul‘).appendChild(frag); 

為DocumentFragment追加子元素,然后再將這個(gè)DocumentFragment加到父列表中,這一系列操作僅僅是一個(gè)DOM操作,因此它比起集中注入要快很多。

如果你不需要將列表對(duì)象當(dāng)做節(jié)點(diǎn)來(lái)操作,更好的方法是用字符串構(gòu)建HTML內(nèi)容:

Javascript代碼

var htmlStr = ‘‘; 

ajaxResult.items.forEach(function(item) { 
    // 構(gòu)建包含HTML頁(yè)面內(nèi)容的字符串 
    htmlStr += ‘<li>‘ + item.text + ‘</li>‘; 
}); 

// 通過(guò)innerHTML設(shè)定ul內(nèi)容 

document.querySelector(‘ul‘).innerHTML = htmlStr; 

這當(dāng)中也只有一個(gè)DOM操作,并且比起DocumentFragment代碼量更少。在任何情況下,這兩種方法都比在每一次迭代中將元素注入DOM更高效。

關(guān)鍵詞:

相關(guān)閱讀: