2012-04-14 9 views
5

Auf einer Webseite habe ich eine ziemlich große Liste von Gegenständen (sagen wir, Produktkarten, jedes enthält Bild und Text) - etwa 1000 von ihnen. Ich möchte diese Liste auf dem Client filtern (nur die Elemente, die nicht herausgefiltert werden, sollten angezeigt werden), aber es gibt ein Rendering-Leistungsproblem. Ich wende einen sehr schmalen Filter an und es bleiben nur noch 10-20 Teile übrig, dann kündige ich es ab (damit alle Elemente wieder angezeigt werden müssen), und der Browser (Chrome auf sehr nettem Rechner) legt für ein oder zwei Sekunden auf.Wie kann man große Mengen von DOM-Elementen mit Javascript optimal darstellen?

ich wieder machen die Liste folgende Routine:

for (var i = 0, l = this.entries.length; i < l; i++) { 
    $(this.cls_prefix + this.entries[i].id).css("display", this.entries[i].id in dict ? "block" : "none") 
} 

dict ist der Hash der erlaubten Elemente Ide

Diese Funktion selbst sofort ausgeführt wird, ist es, dass Rendering auflegt. Gibt es eine optimalere Methode zum erneuten Rendern als die Eigenschaft "display" von DOM-Elementen zu ändern?

Vielen Dank für Ihre Antworten im Voraus.

+1

Sie sind überrascht Das erneute Rendern von 1000 Elementen dauert 1-2 Sekunden? Da ich bezweifle, dass 1000 Elemente in jedem Moment sichtbar sind, sollten Sie vielleicht mit den sichtbaren Elementen umgehen und dann im Hintergrund arbeiten, um den Rest verfügbar zu machen (50 pro Durchgang mit setTimeout() zwischen jedem Batch, um den Browser am Leben zu halten). Oder vielleicht solltest du nur neu rendern, wenn sie tatsächlich durch Scrollen sichtbar werden. Es hilft Ihnen auch nicht, 1000 separate Selektor-Operationen auszuführen, die jeweils das gesamte DOM durchsuchen müssen. – jfriend00

+0

Geben Sie uns ein jsFiddle zur Bearbeitung und ich bin mir sicher, dass wir die Switchover-Leistung um den Faktor 10x verbessern konnten. Es gibt eine Menge saftiges Fett in diesem Code. – jfriend00

Antwort

4

Warum 1000 Artikel laden? Zuerst sollten Sie etwas wie Paginierung betrachten. Zeigt ungefähr 30 Elemente pro Seite an. Auf diese Weise laden Sie nicht so viel.

dann, wenn Sie wirklich in dieser "Schleife eine Menge von Elementen" sind, in Betracht ziehen, Timeouts zu verwenden. here's a demo Ich hatte einmal, dass die Folgen der Looping veranschaulicht. Sie blockiert die Benutzeroberfläche und führt dazu, dass der Browser insbesondere bei langen Schleifen verzögert wird. Wenn Sie jedoch Timer verwenden, verzögern Sie jede Iteration, damit der Browser ab und zu etwas atmen kann, bevor die nächste Iteration beginnt.

eine andere Sache zu beachten ist, dass Sie vermeiden sollten repaints and reflows, was bedeutet, vermeiden, Elemente zu bewegen und ändern Stile, die oft, wenn es nicht notwendig ist. Ein weiterer Tipp besteht darin, die Knoten, die nicht sichtbar sind, aus dem DOM zu entfernen. Wenn Sie nichts anzeigen müssen, entfernen Sie es. Warum verschwendet man etwas, das man nicht sieht?

+1

Vielen Dank für den 'Reflow'-Tipp - es ist einfach unverzeihlich, nicht über die Maschinerie dieses süßen Browsers Bescheid zu wissen, selbst für einen Neuling wie mich. Ich habe den Container der Liste aus DOM entfernt, die Anzeigeeigenschaften von Elementen geändert und den Container dann wieder an DOM zurückgegeben. Voila, kein Reflow - kein Aufhängen! –

-3

Dude - der beste Weg, um "große Mengen von DOM-Elementen" zu behandeln, ist es NICHT auf dem Client zu tun, und/oder verwenden Sie Javascript nicht, wenn Sie es vermeiden können.

Wenn es keine bessere Lösung gibt (und ich bin mir sicher, dass es das wahrscheinlich gibt!), Dann partitionieren Sie zumindest Ihren Arbeitssatz auf das, was Sie in diesem Moment tatsächlich anzeigen müssen (statt der ganzen, großen, honkin enchilada) !)

+3

Ich habe Ihre Antwort abgelehnt, weil es nicht unbedingt falsch ist, große Mengen von DOM-Elementen auf dem Client/JavaScript zu verwenden.Durchschnittliche Computer können DOM-Updates mit Zehntausenden (wenn nicht mehr) Elementen innerhalb einer Sekunde verarbeiten, vorausgesetzt, dass Sie die Komplexität von Algorithmen, Reflow-Prozessen usw. minimieren. In der Praxis kann dies oft viel reaktionsschneller sein als ein Rundweg zu einem Server , vor allem, weil der Client das DOM immer noch mit dem vom Server bereitgestellten HTML aktualisieren wird. Das Problem liegt nicht in JavaScript, sondern darin, wie es verwendet wird. –

+1

Sagen "Javascript nicht verwenden" im Jahr 2014 für Client-Seite Rendering ist sehr schlecht. Vor allem, wenn wir Google, Mozilla, Microsoft, etc. jedes Jahr Millionen von Dollar investieren, um WEB schneller, besser und für den Endbenutzer kostenlos zu machen. Vielleicht ist das der Grund, warum Sie für aktuelle Handels-Apps, Cloud-Lösungen, Musik-Player, CAD- und Grafikanwendungen, riesige Geschäfte (Sie nennen es alles) einen Browser benötigen, den Sie kostenlos herunterladen können. – Martin

0

Sie können den setTimeout Trick verwenden, der die Schleifenaufrufe vom Hauptthread auslädt und verhindert, dass der Client einfriert. Ich vermute, dass die gesamte Verarbeitung - von Anfang bis Ende - würde die gleiche Menge an Zeit dauern, aber zumindest auf diese Weise die Schnittstelle nach wie vor verwendet werden kann, und das Ergebnis ist eine bessere Benutzererfahrung:

for (var i = 0, l = this.entries.length; i < l; i++) { 
    setTimeout(function(){ 
    $(this.cls_prefix + this.entries[i].id).css("display", this.entries[i].id in dict ? "block" : "none") 
    }, 0); 
}