Пару лет назад я провел эксперимент на этом. Намного быстрее присвоить свойству innerHTML
элемента для создания сложной структуры, чем использовать повторные вызовы createElement
appendChild
insertBefore
и т. Д. Я выкопал пост, который я сделал об этом (в список рассылки Prototype & script.aculo.us); ниже.
Помните, что анализ HTML и его рендеринг быстро - это , что делают браузеры , и они высоко оптимизированы для этого. Если вы присваиваете строку со сложной структурой HTML в свойстве innerHTML
элемента контейнера, вы совершаете одно отключение от уровня JavaScript до уровня рендеринга браузера, после чего браузер выполняет синтаксический анализ и рендеринг Код может продолжаться непрерывно.
Напротив, если вы создаете какую-то сложную структуру с использованием DOM API, не только происходит много межуровневых путешествий (JavaScript -> браузер -> JavaScript), но и браузер также должен работать с DOM API, а не его внутренними структурами.
Следовательно, обычно стоит обратить внимание на хорошо написанный движок шаблонов JavaScript (если вы хотите сделать это на стороне клиента). Обычно они «компилируют» шаблон один раз в легко обрабатываемую форму, и во время обработки для определенного набора данных они используют приемы, такие как построение строки в виде фрагментов в массиве с помощью Array#push
, а затем получение окончательного результата. через Array#join
, передавая ""
в качестве разделителя. Для больших строк это может быть быстрее, чем конкатенация строк, хотя зависит ли это (и в какой степени) от очень от реализации (Firefox SpiderMonkey против Chrome V8 против IE JScript), в отличие от innerHTML
по сравнению с DOM, который меняется только на намного быстрее.
Вот список рассылки сообщение от пары лет назад, о котором я говорил (в основном то, что я говорю выше; вау, это было два года назад), * 1030 * вот Пасти это означает, что вот что скопировано в JSBin , и наконец ... вот код: (Обратите внимание, что код не предназначен для красоты и радость навсегда, это был быстрый взлом ... Тем не менее, да, я хотел бы думать, что взломаю что-нибудь немного лучше сейчас, два года спустя.)
Возможно, стоит преобразовать это во что-то, что будет работать на jsPerf . Боюсь, сейчас не время для этого.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<style>
#log {
border-bottom: 1px solid black;
}
#log p {
margin: 0;
padding: 0;
}
</style>
<script type='text/javascript' src='//ajax.googleapis.com/ajax/libs/prototype/1/prototype.js'></script>
<script type='text/javascript'>
document.observe('dom:loaded', function() {
$('btnDOMDirect').observe('click', useDOMDirect);
$('btnPrototypeDOM').observe('click', usePrototypeDOM);
$('btnHTML').observe('click', useHTML);
});
var numRows = 10;
var numCols = 10;
function usePrototypeDOM(evt)
{
var table;
var tbody;
var tr;
var td;
var row;
var col;
var start;
var end;
start = (new Date()).getTime();
table = new Element('table');
tbody = new Element('tbody');
table.appendChild(tbody);
for (row = 0; row < numRows; ++row) {
tr = new Element('tr');
tbody.appendChild(tr);
for (col = 0; col < numCols; ++col) {
td = new Element('td');
td.update('Row ' + row + ', col ' + col);
tr.appendChild(td);
}
}
$('targetTable').update(table);
end = (new Date()).getTime();
log('DOM took ' + (end - start) + 'ms');
}
function useDOMDirect(evt)
{
var table;
var tbody;
var tr;
var td;
var row;
var col;
var start;
var end;
if (Prototype.Browser.IE) {
alert("DOM direct doesn't work on IE because I used table elements. Sorry. The other two work.");
return;
}
start = (new Date()).getTime();
table = document.createElement('table');
tbody = document.createElement('tbody');
table.appendChild(tbody);
for (row = 0; row < numRows; ++row) {
tr = document.createElement('tr');
tbody.appendChild(tr);
for (col = 0; col < numCols; ++col) {
td = document.createElement('td');
td.update('Row ' + row + ', col ' + col);
tr.appendChild(td);
}
}
$('targetTable').update(table);
end = (new Date()).getTime();
log('DOM took ' + (end - start) + 'ms');
}
function useHTML(evt)
{
var html;
var row;
var col;
var start;
var end;
start = (new Date()).getTime();
html = '<table><tbody>';
for (row = 0; row < numRows; ++row) {
html += '<tr>';
for (col = 0; col < numCols; ++col) {
html += '<td>Row ' + row + ', col ' + col + '</td>';
}
html += '</tr>';
}
html += '</tbody></table>';
$('targetTable').update(html);
end = (new Date()).getTime();
log('HTML took ' + (end - start) + 'ms');
}
function log(msg)
{
var l;
var p;
l = $('log');
if (l) {
p = new Element('p');
p.update(msg);
l.appendChild(p);
}
}
</script>
</head>
<body>
<input type='button' id='btnDOMDirect' value='DOM Direct' />
<input type='button' id='btnPrototypeDOM' value='Prototype DOM' />
<input type='button' id='btnHTML' value='HTML' />
<div id='log'></div>
<div id='targetTable'></div>
</body>
</html>