2010-09-21 10 views
13

Mam aplikację internetową, na której będziemy włożeniem setki elementów w DOMNajlepszy sposób, aby wstawić setki elementów DOM na stronę dynamicznie przy zachowaniu wysokiej wydajności

Zasadniczo robię

$('#some_element').html('<lots of html here>'); 

wielokrotnie. W niektórych przypadkach może zajść potrzeba zrobienia tego, co trzeba. Wcześniejsze doświadczenie polegało na wstawianiu tekstu w formacie HTML przy użyciu załącznika lub ustawieniu elementu innerHTML elementu na wolny.

Słyszałem, że można zwiększyć wydajność, najpierw umieszczając elementy w fragmencie DOM, a następnie przesuwając jego lokalizację do wnętrza wybranego elementu.

Skuteczność tego jest kluczowa. Czy macie jakieś wskazówki lub sugestie dotyczące maksymalizacji wydajności? Jakieś hacki, które mogę zrobić, aby zrobić to szybko?

Edycja: jak wspomniano w komentarzu: Aplikacja zawiera strumienie różnych danych w czasie rzeczywistym, więc musi być w stanie stale dodawać nowe elementy DOM do reprezentowania nowych danych. (Może to również prowadzić do innego problemu z posiadaniem zbyt dużej liczby elementów DOM, więc trzeba by było użyć elementów, które są zbyt stare).

+3

Biorąc pod uwagę wymagania, twoje obecne podejście wydaje się rozsądne. Czy obecnie jest wolny? –

+0

Tak, istnieje niewielkie opóźnienie, ponieważ przeglądarka renderuje nowy html. Tak więc przeglądarka czuje się zamrożona przez 300ms do 600ms. Ale ponieważ jest więcej danych, nie chcę tego wzrostu, o co się martwię. – rksprst

+1

Czy możesz podać przykładową stronę internetową? –

Odpowiedz

11

Tylko nie rób html() (lub użyć swojego ojczystego kuzyna innerHTML = …) wielokrotnie. Spakuj swój kod HTML w jedną zmienną i wykonaj html() tylko jeden raz (lub kilka razy, jak to możliwe). Np .:

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(""); 

Zobacz także Quirksmode entry on innerHTML a strona W3C DOM vs. innerHTML.

Aktualizacja: Wczoraj znalazłem niesamowite artykuł When innerHTML isn't Fast Enough Stevena Levithan o jego funkcji replaceHtml, który jest nawet szybciej niż przy użyciu tylko innerHTML, ponieważ usuwa węzły DOM, które mają być zastąpione przy użyciu standardowych manipulacji DOM przedinnerHTML jest stosowany:

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; 
}; 
+0

Aplikacja zawiera strumienie różnych danych w czasie rzeczywistym, więc musi być w stanie stale dodawać nowe elementy DOM. – rksprst

+0

@rksprst: ale jeśli zrobisz to w jednym przebiegu, nie zauważysz, ponieważ wykonywanie skryptu blokuje ponowne wysyłanie. "Właściwie to, co pokazuję, to umieszczanie elementów w fragmencie DOM, a następnie przesuwanie jego lokalizacji do wnętrza elementu". Nie ma szybszej drogi, przynajmniej z tego, co wiem. –

+0

Dzięki za pomoc, dość późno na torze, po prostu wskazówka dla innych - stwierdziłem, że muszę dodać var ​​buf = [], i = 0; aby mój kod działał. – dpmguise

0

czasie rzeczywistym transmisji strumieniowej powinna aktualizacja nie dołączy. Jak wspomniano, użyj bufora. Kolejną rzeczą, którą możesz zrobić, jest.

var buffer = []; 
setInterval(function(){ $("#div").html(buffer.join(""); buffer = []; }, 1000); 

buffer.push("html"); 
buffer.push("html"); 

Ustaw limit czasu na wszystko, czego potrzebujesz, a następnie opróżni bufor i dołączy go.

Oto funkcja i interwał, z których można korzystać.

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); 
}; 
+1

Współdziałanie JS nie działa w ten sposób; nie można wyrejestrować "w środku tego". – raylu

+0

@raylu Dobry punkt, dzięki. Ta odpowiedź jest wcześniejsza niż wiele moich doświadczeń z JS. –

1

Aby wyjaśnić, co Marcel powiedział w swojej odpowiedzi:

manipulacji DOM (używając appendTo, tworzenie elementu, TextNode'S, etc) to rzędy wielkości wolniejsze niż po prostu czytać/pisać innerHTML.

Powiązane problemy