JQuery: самая быстрая вставка DOM?
У меня возникло такое плохое чувство, что я вставляю большие количества HTML.
Допустим, мы получили:
var html="<table>..<a-lot-of-other-tags />..</table>"
и я хочу поместить это в
$("#mydiv")
раньше я сделал что-то вроде
var html_obj = $(html);
$("#mydiv").append(html_obj);
Правильно ли, что jQuery анализирует html
для создания объектов DOM? Ну, это то, что я где-то читал (UPDATE: Я имел в виду, что я прочитал, jQuery анализирует html для создания всего дерева DOM вручную - его бессмыслица правильно?! ), поэтому я изменил свой код:
$("#mydiv").attr("innerHTML", $("#mydiv").attr("innerHTML") + html);
Чувствует себя быстрее, не так ли? И правильно ли это эквивалентно:
document.getElementById("mydiv").innerHTML += html
? или jquery делает некоторые дополнительные дорогие вещи в фоновом режиме?
Хотелось бы также изучить альтернативы.
Ответы
Ответ 1
innerHTML замечательно быстро, и во многих случаях вы получите наилучшие результаты, просто установив это (я бы просто использовал append).
Однако, если в "mydiv" уже много чего, вы вынуждаете браузер анализировать и снова отображать все это содержимое (все, что было раньше, плюс все ваше новое содержимое). Вы можете избежать этого, добавив фрагмент документа на "mydiv":
var frag = document.createDocumentFragment();
frag.innerHTML = html;
$("#mydiv").append(frag);
Таким образом, только ваш новый контент получает синтаксический анализ (неизбежно), а существующий контент - нет.
EDIT: Мой плохой... Я обнаружил, что innerHTML не поддерживается на фрагментах документа. Вы можете использовать ту же технику с любым типом node. Например, вы можете создать корневую таблицу node и вставить innerHTML в это:
var frag = document.createElement('table');
frag.innerHTML = tableInnerHtml;
$("#mydiv").append(frag);
Ответ 2
Попробуйте следующее:
$("#mydiv").append(html);
Другие ответы, включая принятый ответ, медленнее на 2-10x: jsperf.
Принятый ответ не работает в IE 6, 7 и 8, потому что вы не можете установить innerHTML
из элемента <table>
из-за ошибки в IE: jsbin.
Ответ 3
Чего вы пытаетесь избежать? "Плохое чувство" невероятно расплывчато. Если вы слышали "DOM медленный" и решили "избегать DOM", тогда это невозможно. Каждый способ вставки кода на страницу, включая innerHTML, приведет к созданию объектов DOM. DOM - это представление документа в вашей памяти браузера. Вы хотите создать объекты DOM.
Причина, по которой люди говорят, что DOM медленная, заключается в том, что создание элементов с document.createElement()
, который является официальным интерфейсом DOM для создания элементов, медленнее, чем использование нестандартного свойства innerHTML в некоторых браузерах. Это не означает, что создание объектов DOM является плохим, необходимо создать объекты DOM, иначе ваш код ничего не сделает.
Ответ 4
Ответ об использовании фрагмента DOM находится на правильном пути. Если у вас есть куча html-объектов, которые вы постоянно вставляете в DOM, вы увидите некоторые улучшения скорости с помощью фрагмента. Это сообщение Джона Ресига объясняет это довольно хорошо:
http://ejohn.org/blog/dom-documentfragments/
Ответ 5
Для начала напишите script, сколько времени потребуется, чтобы сделать это 100 или 1000 раз с каждым методом.
Чтобы убедиться, что повторы не оптимизированы, я не эксперт в JavaScript-машинах - изменяйте html, который вы вставляете каждый раз, например, добавив "0001", затем "0002", затем "0003", в определенной ячейке таблицы.
Ответ 6
Самый быстрый способ добавления элементов
Самый быстрый способ добавить к дереву DOM - это буферизировать все ваши добавления в один фрагмент DOM, а затем добавить фрагмент dom в dom.
Это метод, который я использую в своем игровом движке.
//Returns a new Buffer object
function Buffer() {
//the framgment
var domFragment = document.createDocumentFragment();
//Adds a node to the dom fragment
function add(node) {
domFragment.appendChild(node);
}
//Flushes the buffer to a node
function flush(targetNode) {
//if the target node is not given then use the body
var targetNode = targetNode || document.body;
//append the domFragment to the target
targetNode.appendChild(domFragment);
}
//return the buffer
return {
"add": add,
"flush": flush
}
}
//to make a buffer do this
var buffer = Buffer();
//to add elements to the buffer do the following
buffer.add(someNode1);
//continue to add elements to the buffer
buffer.add(someNode2);
buffer.add(someNode3);
buffer.add(someNode4);
buffer.add(someN...);
//when you are done adding nodes flush the nodes to the containing div in the dom
buffer.flush(myContainerNode);
Используя этот объект, я могу отображать ~ 1000 элементов на экране ~ 40 раз в секунду в firefox 4.
Здесь используется прецедент.
Ответ 7
Я создаю гигантскую строку, а затем добавлю эту строку в jquery.
Работает хорошо и быстро, для меня.
Ответ 8
Вы упоминаете, что заинтересованы в альтернативах. Если вы посмотрите на список связанных с DOM плагинов jQuery, вы найдете несколько, посвященных программному созданию деревьев DOM. См. Например SuperFlyDom или DOM Elements Creator; но есть и другие.