2012-04-05 18 views
4

Was ich tun möchte: Gruppiere alle ähnlichen Elemente auf einer Seite (einer bestimmten Art) in ein Objekt, mit dem ich später iterieren kann - oder füge umfassende Änderungen an jedem Element ein.jQuery: add() Leistung; Gibt es einen besseren Weg?

Mein Code ist erfolgreich bei der Ausführung der Aufgabe, aber wenn die Anzahl der Elemente auf 200-300 + wächst, fällt die Leistung drastisch ab und Benutzer haben es bemerkt. Ich habe die fehlerhaften Codezeilen isoliert und möchte wissen, ob es eine andere Möglichkeit gibt, das gleiche Problem zu lösen.

Die Funktion add() scheint die problematische Operation zu sein, basierend auf den Timern, die ich um sie herum platziert habe. Zuerst ist die Zeit, die zur Ausführung der Operation benötigt wird, 0,001, wächst aber, bis die Anzahl der Elemente 300 erreicht, und es dauert ~ 0,1 Sekunde für jedes zusätzliche Element und setzt die Verlangsamung fort.

Ich habe researched (and more) für jQuery leistungssteigernde Fähigkeiten und habe ein paar von ihnen (nämlich 3) implementiert, aber sie haben mir keine nennenswerten Leistungssteigerungen gegeben. Erstaunlicherweise führt dieser Code innerhalb von 1 Sekunde für Firefox (300+() hinzuzufügen, ruft), während Chrome und IE etwa 10-20x länger dauern oder mehr ...

Hier ist mein Code (!):

rowsToChange = $([]); 
// Grab all the ids greater than whichever one I'm currently looking at: 
var arr = $.makeArray($("[id^=stackLocatorLinkFillUp]:gt("+(uniqueID-1)+")")); 
for (var i=0; i<arr.length; i++) { 
    $this = arr[i]; 
    // <<< VARIOUS CONDITIONALS that make this as selective as possible REMOVED >>> 
    startTimer = new Date().getTime(); 
    // ************************** 
    // PROBLEMATIC LINE FOLLOWS when 200+ records: 
    rowsToChange = rowsToChange.add($this); 
    // Grows from .001 to .1xx after 300 iterations 
    console.log("innertiming:"+(new Date().getTime() - startTimer)/1000); 
    // ************************** 
} 

das Endergebnis sieht wie folgt aus (via Chrome Inspector):

[<div style=​"display:​none" id=​"stackLocatorLinkFillUp1">​itemType=BOUND&ccLocale=PERIODICAL​</div>​, 
<div style=​"display:​none" id=​"stackLocatorLinkFillUp2">​itemType=BOUND&amp;ccLocale=PERIODICAL​</div>​, 
... 
] 

Schließlich ich verarbeiten alle diese wie folgt (die ich Liebe die Einfachheit!):

var superlink = "...new <a> goodness to display for all elements..."; 
rowsToChange.html(superlink).css("display","block"); 

Das sah aus wie es eine gültige Lösung (different add method?) sein könnte, aber ich würde es vorziehen, zusammen sammelte eine Liste von Objekten fortzusetzen, so dass die letzte Zeile seiner Magie arbeiten.

(am not i am wies darauf hin, dass die folgenden nicht wahr ist - in Bezug auf Verkettung, dank ‚bin nicht ich bin‘)

Es scheint, wie die add() Betrieb sein müssen Strings verketten da, dass man zu sein scheint von die Hauptprobleme, mit denen andere konfrontiert sind. Aber meine add() -Anweisung in + = umzuwandeln sieht nicht so aus, als ob sie funktioniert.

Vielen Dank für das Auschecken;

Chrome: 18.0.1025.142 m der folgende: 11.0 IE: 8.0.7600.16385

+0

Was ist "Superlink"? Sie zeigen nicht, was Sie genau mit "rowsToChange" machen. – Pointy

+0

Die '.add()' Methode ist definitiv keine Verkettung von Strings. Das DOM ist keine Zeichenfolge. Vielleicht möchten Sie einen Blick auf ['.pushStack()'] werfen (http://api.jquery.com/pushstack/) –

+0

Danke Pointy; In meinem echten Code abstrahierte ich die Methode, was zu einem neuen Namen führte. Superlink erhält einen Platzhalter. Sorry für die Verwirrung – veeTrain

Antwort

4

Erste Beobachtung: add speichert das vorhergehende Element festgelegt. Versuchen Sie stattdessen rowsToChange = jQuery.merge(rowsToChange, [$this]);.

Zweite Beobachtung: Es scheint, als würde rowsToChange am Ende genau das gleiche Element sein wie das, das Sie $.makeArray angerufen haben. Warum nicht einfach das Originalset speichern?

+0

Re: Zweite Beobachtung; toller Punkt! Ich habe nicht meinen gesamten Code eingeschlossen, um nicht abzulenken; Es gibt viele Bedingungen, die auftreten müssen, um zu rowsToChange hinzugefügt zu werden :-) Ich versuche deine Merge-Idee! – veeTrain

+0

DCoder - genialer Vorschlag und Ihre erste Beobachtung scheint die Lösung zu sein, die ich brauche; es funktioniert fast zu schnell, um zu glauben, also werde ich dreifach überprüfen, aber werde zurückkehren und Ihre Antwort höchstwahrscheinlich akzeptieren. Vielen Dank! (S. S., Merge erforderlich, um [] um $ this) – veeTrain

+0

DCoder: Ich habe Ihre Antwort akzeptiert und implementiert; Was für eine tolle Lösung! Es macht genau das, was ich wollte und blitzschnell über alle drei Browser hinweg. Was ich über Brackets rund um [$ this] erwähnt habe, änderte sich jedoch. Anscheinend sind die Klammern ** unnötig (wie du vermutet hast), als ich eine $ .each() - Schleife und _necessary_ benutzt habe, als ich eine for-Schleife benutzt habe. Ich werde beide in einer neuen Antwort erwähnen, aber lass deine akzeptieren. Ich danke dir sehr! – veeTrain

0

DCoder zeigt, wie Sie die Informationen zusammenführen können, wenn Sie eine for-Schleife verwenden. Wenn Sie jedoch hierher kommen und eine .each()-Schleife verwenden, verwenden Sie Folgendes.

Der Hauptunterschied besteht darin, dass Klammern je nach Struktur von 'this' unnötig/notwendig sind.Es scheint auch allgemein akzeptiert zu sein, dass .each()mindestens etwas langsamer als die native Javascript for Schleife ist. (evidence from 2009) (timing test_copied from question above)

var $this, rowsToChange = $([]); 
// slower than a for loop 
$("[id^=stackLocatorLinkFillUp]:gt("+(uniqueID-1)+")").each(function() { 
    // If statements <removed> that decide whether or not to include in the new container 
    $this = $(this); // probably unnecessary under most situations 
    rowsToChange = jQuery.merge(rowsToChange, $this); 
}); 

auf jedem Stück Betreiben der neuen Untergruppe entschied die if-Anweisungen entfernt!

rowsToChange.html("..."); 

Vielen Dank an alle, die die Frage angesehen, sich die Zeit genommen haben zu antworten, sie gewählt haben, usw.!

Verwandte Themen