2011-01-19 16 views
7

W Firefoksie, jestem wstawiania tekstu do ~ 500 DIV przy użyciu tego kodu:Jak poprawić wydajność wstawiania tekstu do elementu HTML?

$(".divs").text("default"); // ~500 DIVs 

na moim komputerze, to konsekwentnie zajmuje 9msjeśli DIV są puste. Jednak ten sam kod konsekwentnie przyjmuje wartość 18ms, jeśli elementy DIV zawierają już tekst.

Dlaczego puste DIV jest 2x szybsze przy wstawianiu tekstu (czy jQuery musi najpierw opróżnić DIV)? Czy istnieje sposób na poprawę wydajności zastępowania tekstu w DIV, który już zawiera tekst?

Uwaga: W IE 7 różnice prędkości nie były tak dramatyczne. Wstawienie tekstu do pustego DIV było około 1,5 razy szybsze.

+3

Ścigasz różnicę wydajności 9 ms? I nie ulega wątpliwości, że jeśli * naprawdę * chcesz, aby było szybkie, zrobiłbyś to z prostym starym JS. Biblioteki ułatwiają rozwój, ale rzadko oferują wzrost wydajności w porównaniu z używaniem kodu waniliowego. – ken

+4

Tak. Ścigam różnicę wydajności 2x. –

+6

Jako ćwiczenie akademickie uważam, że jest to dobre pytanie, ale w przypadku twojego przypadku użycia, myślę, że jesteś daleko poza punktem zmniejszających się zysków. Żaden użytkownik nie zauważy różnicy 9 ms; w tym przypadku żaden użytkownik nie zauważy różnicy 90 ms. – ken

Odpowiedz

6

Jeśli chcesz najszybsze rozwiązanie dla wszystkich przeglądarek używać textContent jeśli jest obsługiwane i awaryjne do innerText/innerHTML inaczej [Test] (znając gotchas).

/** 
* Replaces text for all elements in the given array. 
* @param {Array} elems 
* @param {String} text 
*/ 
var replaceText = (function(){ 
    var dummy = document.createElement("div"); 
    dummy.innerHTML = "text"; 
    var TEXT = (dummy.textContent === 'text') ? 'textContent' : 'innerText'; 
    return function(elems, text) { 
    for (var i = elems.length; i--;) { 
     elems[i][TEXT] = text; 
    } 
    }; 
})(); 

Szybsze niż jQuery tekście:

  • 4x na IE 8
  • 2.2x na Firefox 4b11
  • 1.3x na Chrome
+0

Wow, bardzo miło! –

+0

Możesz zaakceptować odpowiedź, jeśli rozwiązała Twój problem :) – galambalazs

1

Jeśli nie musisz wymazywać znaczników html (np. Zastępując <a> przez &lt;a&gt;), wtedy .html może być szybsze. Również tak musi opróżnić div przed zastąpieniem go nową treścią.

6

Jeśli tekst wstawiasz robi NIE trzeba uciec, to może chcesz spróbować następujących sposobów:

$(".div").each(function(){ 
    this.innerHTML = "default"; 
}); 

jQuery wykonuje pewne przetwarzanie tekstu podczas korzystania z method .text().

Musimy zdawać sobie sprawę, że ta metoda ucieka ciąg dostarczane jako potrzeby tak, że będzie renderowanie prawidłowo w HTML. Aby to zrobić, wywołuje metodę DOM .createTextNode(), , która zastępuje znaki specjalne z ich odpowiednikami encji HTML (np. < dla <).

Edit Aby uniknąć kary metody .each() można spróbować wykonać następujące czynności:

var divs = $(".divs"), 
    i = 0, 
    len = divs.length; 
while(len--) { 
    divs[len].innerHTML = "default"; 
} 

Jeśli to nie ci żadnych korzyści wydajności to jest to na pewno kwestia wdrożenia przeglądarki. Przynajmniej to wyklucza problemy/błędy wydajności jQuery.

+0

Dzięki za pomoc. 1) Trwa to dłużej z powodu pętli .each() i 2) Kod jest jeszcze szybszy, gdy DIV są puste. –

+0

Może to spowodować problem z przeglądaniem przeglądarki! wiesz, że musisz zwolnić pamięć tych strun. tylko przypuszczenie. Czy próbowałeś już różnych przeglądarek? –

+0

sprawdź moje edytowane rozwiązanie –

3

Tak, przyczyna ta metoda się wolniej, gdy elementy mają elementy potomne dlatego .text() metoda jQuery najpierw uruchamia metodę .empty() a następnie .append(document.createTextNode(text))

Od jQuery.text

// ... 
return this.empty().append((this[0] && this[0].ownerDocument || document).createTextNode(text)); 
// ... 

Powód 'm wskazuje na to, że metoda ta wywołuje metodę , która usuwa wszelkie dane i/lub zdarzenia związane z jej węzłami potomnymi, a następnie wykonuje standardową metodę .removeChild() na wszystkich swoich węzłach potomnych w celu ich usunięcia. główny powód, dla którego elementy div, które zawierają już tekst, wolniej się aktualizują.

Rozwiązaniem problemu jest napisanie własnych, wanilii, funkcji javaScript do aktualizacji tekstu elementów div, ale upewnij się, że nie dołączasz do nich zdarzeń ani danych kliknięć za pośrednictwem jQuery, ponieważ będziesz najbardziej zdecydowanie mają pewne wycieki pamięci.

3

Można zwiększyć wydajność, ponownie wykorzystując istniejący węzeł tekstowy.

Element DIV zawierający tylko tekst to element DOM zawierający jeden węzeł potomny, którego typem jest węzeł tekstowy. Treść tekstu jest przechowywana w tym węźle tekstowym, a nie w jego macierzystym elemencie DIV.

Głównym problemem z metod, takich jak .text() w jQuery lub .innerHTML() w HTML DOM, a nawet .innerText() i .textContent(), jest to, że wszystkie one utworzyć nowy węzeł tekstowy (nawet jeśli już istnieje). Dokładniej, wszystkie wyżej wymienione metody zaczynają się od usunięcia węzłów potomnych DOM, w tym ewentualnie istniejącego węzła tekstowego (jest to również realizowane przez implementacje innerHTML, innerText i textContent). Pozostawia to element kontekstu (DIV, w twoim przypadku) pusty, bez żadnych dzieci. Następnie tworzą nowy węzeł potomny typu tekstowego , przypisując do niego nowy tekst i dołączając go do elementu kontekstu. innerHTML ponadto próbuje przeanalizować wejściowy ciąg HTML i skonstruować z niego fragment DOM.

Najszybszy sposób, że wiem na zastąpienie istniejącego węzła tekstu jest następująca:

var divs = $(".divs").get(), 
    len = divs.length; 
while(--len) { 
    divs[len].firstChild.data = "default"; 
} 

Ta metoda nie tworzy nowy węzeł dziecko, ale po prostu zastępuje tekst istniejącego węzła tekstowego. Oczywiście ta metoda zakłada, że ​​węzeł tekstowy już istnieje. Aby to działało, początkowy dokument może zostać zainicjowany za pomocą niepustego tekstu wewnątrz elementów DIV (i wykluczając wszelkie inne elementy podrzędne).

Powiązane problemy