Лучший способ вставить сотни элементов 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);
};