Лучший способ вставить сотни элементов DOM в страницу динамически, сохраняя высокую производительность
У меня есть веб-приложение, где мы будем вставлять сотни элементов в DOM
По существу, я делаю
$('#some_element').html('<lots of html here>');
несколько раз. В некоторых случаях мне может понадобиться $('#some_element').appendTo('more html');
Из предыдущего опыта вставка html-текста с помощью добавления или установки элемента innerHTML
элемента выполняется медленно.
Я слышал, что вы можете увеличить производительность, сначала поместив элементы в DOM-фрагмент, а затем переместив свое местоположение внутри нужного элемента.
Производительность этого ключа. У вас есть какие-либо советы или предложения по максимизации производительности? Любые хаки, которые я могу сделать, чтобы сделать это быстро?
Изменить: как указано в комментарии: приложение включает поток различных данных в режиме реального времени, поэтому он должен постоянно добавлять новые элементы DOM для представления новых данных. (Это может также привести к другой проблеме наличия слишком большого количества элементов DOM, поэтому для элементов, которые являются слишком старыми).
Ответы
Ответ 1
Просто не делайте html()
(или используйте его родной кузен innerHTML = …
) несколько раз. Упакуйте свой HTML в одну переменную и делайте html()
только один раз (или как можно меньше раз). Например:.
var buf = [], i = 0;
buf[i++] = "<p>"; /* or use buf.push(string) */
buf[i++] = "some text";
buf[i++] = "some other text";
buf[i++] = "</p>";
element.innerHTML = buf.join("");
Также смотрите запись Quirksmode на innerHTML и W3C DOM vs. innerHTML.
Обновление: Вчера я нашел потрясающую статью Когда innerHTML не будет достаточно быстро Стивеном Левитаном его функция replaceHtml
, которая даже быстрее, чем просто innerHTML
, поскольку она удаляет узлы DOM, которые необходимо заменить, используя стандартную манипуляцию DOM до использования innerHTML
:
function replaceHtml(el, html) {
var oldEl = typeof el === "string" ? document.getElementById(el) : el;
/*@cc_on // Pure innerHTML is slightly faster in IE
oldEl.innerHTML = html;
return oldEl;
@*/
var newEl = oldEl.cloneNode(false);
newEl.innerHTML = html;
oldEl.parentNode.replaceChild(newEl, oldEl);
/* Since we just removed the old element from the DOM, return a reference
to the new element, which can be used to restore variable references. */
return newEl;
};
Ответ 2
Чтобы уточнить, что сказал Марсель в своем ответе:
Обработка DOM (с помощью appendTo, создания Element, TextNode и т.д.) - это порядки величин медленнее, чем просто чтение/запись innerHTML.
Ответ 3
Поток в реальном времени должен обновить не добавляться. Как уже упоминалось, используйте буфер. Другое дело, что вы можете сделать.
var buffer = [];
setInterval(function(){ $("#div").html(buffer.join(""); buffer = []; }, 1000);
buffer.push("html");
buffer.push("html");
Установите тайм-аут на то, что вам нужно, и он будет очищать буфер и добавлять его.
Вот функция и интервал, который вы можете использовать.
var buffer = [];
var wait = 1000; /* ms to wait, 1000 = 1 second */
var htmlId = "puthere"; /* Change this to the div ID */
setInterval(function(){
var tmp = buffer; /* Switch the buffer out quickly so we aren't scrambled
if you addToBuffer in the middle of this */
buffer = [];
document.getElementById(htmlId).innerHTML = tmp.join("");
}, wait);
addToBuffer = function(html){
buffer.push(html);
};