Ich habe einen riesigen Datensatz von mehreren tausend Zeilen mit jeweils etwa 10 Feldern, ungefähr 2 MB Daten. Ich muss es im Browser anzeigen. Der einfachste Ansatz (Daten abrufen, ablegen $scope
, ng-repeat=""
erledigen lassen ) funktioniert einwandfrei, friert den Browser jedoch für etwa eine halbe Minute ein, wenn er anfängt, Knoten in DOM einzufügen. Wie soll ich dieses Problem angehen?
Eine Möglichkeit besteht darin, Zeilen $scope
schrittweise anzuhängen und zu warten, ngRepeat
bis das Einfügen eines Blocks in das DOM abgeschlossen ist, bevor Sie mit dem nächsten fortfahren. AFAIK ngRepeat meldet sich jedoch nicht zurück, wenn das "Wiederholen" beendet ist, sodass es hässlich wird.
Eine andere Möglichkeit besteht darin, Daten auf dem Server in Seiten aufzuteilen und sie in mehreren Anforderungen abzurufen. Dies ist jedoch noch hässlicher.
Ich habe in der Angular-Dokumentation nach etwas Ähnlichem gesucht ng-repeat="data in dataset" ng-repeat-steps="500"
, aber nichts gefunden. Ich bin ziemlich neu in Angular-Methoden, daher ist es möglich, dass ich den Punkt komplett verfehle. Was sind die Best Practices dabei?
limitTo
nur 20 Elemente anzeigen:<p ng-repeat="data in dataset | limitTo:20">{{data}}</p>
Hier werden nur 20 Elemente angezeigt . Dann könnten Sie Seiten verwenden und die nächsten 10 Elemente oder ähnliches anzeigen. :)Antworten:
Ich stimme @ AndreM96 zu, dass der beste Ansatz darin besteht, nur eine begrenzte Anzahl von Zeilen anzuzeigen, schneller und besser UX. Dies könnte mit einer Paginierung oder mit einer unendlichen Schriftrolle erfolgen.
Infinite Scroll mit Angular ist mit dem LimitTo- Filter wirklich einfach . Sie müssen nur das anfängliche Limit festlegen und wenn der Benutzer weitere Daten anfordert (ich verwende der Einfachheit halber eine Schaltfläche), erhöhen Sie das Limit.
Hier ist ein JsBin .
Dieser Ansatz könnte für Telefone ein Problem sein, da sie normalerweise beim Scrollen vieler Daten zurückbleiben. In diesem Fall passt eine Paginierung meiner Meinung nach besser.
Dazu benötigen Sie den Filter limitTo sowie einen benutzerdefinierten Filter, um den Startpunkt der angezeigten Daten zu definieren.
Hier ist ein JSBin mit einer Paginierung.
quelle
Der heißeste - und wohl skalierbarste - Ansatz zur Überwindung dieser Herausforderungen mit großen Datenmengen ist der Ansatz der collectionRepeat-Direktive von Ionic und anderer Implementierungen wie dieser. Ein ausgefallener Begriff dafür ist "Okklusions-Culling" , aber Sie können es wie folgt zusammenfassen: Beschränken Sie die Anzahl der gerenderten DOM-Elemente nicht nur auf eine beliebige (aber immer noch hohe) paginierte Zahl wie 50, 100, 500 ... stattdessen , Limit nur so viele Elemente wie der Benutzer zu sehen .
Wenn Sie so etwas wie das sogenannte "unendliche Scrollen" ausführen , reduzieren Sie die anfängliche DOM-Anzahl etwas, aber sie bläht sich nach ein paar Aktualisierungen schnell auf, da all diese neuen Elemente nur unten angeheftet werden. Das Scrollen kommt zu einem Crawl, da es beim Scrollen nur um die Anzahl der Elemente geht. Es ist nichts Unendliches daran.
Der
collectionRepeat
Ansatz besteht darin, nur so viele Elemente zu verwenden, wie in das Ansichtsfenster passen, und diese dann zu recyceln . Wenn ein Element nicht mehr sichtbar ist, wird es vom Renderbaum getrennt, mit Daten für ein neues Element in der Liste gefüllt und dann am anderen Ende der Liste wieder mit dem Renderbaum verbunden. Dies ist der schnellste Weg, den der Mensch kennt, um neue Informationen in das DOM und aus dem DOM heraus zu erhalten, wobei eine begrenzte Anzahl vorhandener Elemente verwendet wird und nicht der traditionelle Zyklus von Erstellen / Zerstören ... Erstellen / Zerstören. Mit diesem Ansatz können Sie wirklich eine unendliche Schriftrolle implementieren .Beachten Sie, dass Sie Ionic nicht verwenden müssen, um / hack / adapt
collectionRepeat
oder ein anderes Tool wie dieses zu verwenden. Deshalb nennen sie es Open Source. :-) (Das heißt, das Ionic-Team macht einige ziemlich geniale Dinge, die Ihrer Aufmerksamkeit wert sind.)Es gibt mindestens einen hervorragendes Beispiel dafür, wie man in React etwas sehr Ähnliches macht. Nur anstatt die Elemente mit aktualisiertem Inhalt zu recyceln, entscheiden Sie sich einfach dafür, nichts in der Baumstruktur zu rendern, was nicht angezeigt wird. Bei 5000 Artikeln ist es blitzschnell, obwohl die sehr einfache POC-Implementierung ein bisschen Flimmern zulässt ...
Auch ... um einige der anderen Beiträge wiederzugeben, ist die Verwendung sehr
track by
hilfreich, selbst bei kleineren Datensätzen. Betrachten Sie es als obligatorisch.quelle
Ich empfehle dies zu sehen:
AngularJS optimieren: 1200 ms bis 35 ms
Sie haben eine neue Richtlinie erstellt, indem sie ng-repeat in 4 Teilen optimiert haben:
Das Projekt ist hier auf Github:
Verwendung:
1- Fügen Sie diese Dateien in Ihre einseitige App ein:
2- Modulabhängigkeit hinzufügen:
3- ng-repeat ersetzen
Genießen!
quelle
sly-repeat
aber nichts half mir, die Ergebnisse sind immer noch langsam und Browser-Verzögerungen bekommen auch Verstöße[Violation] 'setTimeout' handler took 54ms
,[Violation] 'scroll' handler took 1298ms
Neben all den oben genannten Hinweisen wie Track by und kleineren Loops hat mir dieser auch sehr geholfen
Dieser Code druckt den Namen, sobald er geladen wurde, und hört danach auf, ihn anzusehen. In ähnlicher Weise könnte es für ng-Wiederholungen als verwendet werden
Es funktioniert jedoch nur für AngularJS Version 1.3 und höher. Von http://www.befundoo.com/blog/optimizing-ng-repeat-in-angularjs/
quelle
::
die Wiederholung als auch den Ausdruck? Die Dokumente sagen etwas anderes, aber ich bin mir nicht sicher, wie ich testen kann, ob dies funktioniert. docs.angularjs.org/guide/expressionSie können "Track by" verwenden, um die Leistung zu steigern:
Schneller als:
Ref: https://www.airpair.com/angularjs/posts/angularjs-performance-large-applications
quelle
Wenn alle Ihre Zeilen gleich hoch sind, sollten Sie sich unbedingt die virtualisierende ng-repeat ansehen: http://kamilkp.github.io/angular-vs-repeat/
Diese Demo sieht sehr vielversprechend aus (und unterstützt das Trägheits-Scrollen)
quelle
Regel Nr. 1: Lassen Sie den Benutzer niemals auf etwas warten.
In Anbetracht dessen erscheint eine lebenswachsende Seite, die 10 Sekunden benötigt, viel schneller als 3 Sekunden vor einem leeren Bildschirm zu warten und alles auf einmal zu erhalten.
Anstatt also make schnell die Seite, lassen Sie einfach die Seite erscheinen , schnell zu sein, auch wenn das Endergebnis ist langsamer:
Der obige Code lässt die Liste zeilenweise wachsen und ist immer langsamer als das gleichzeitige Rendern. Aber für den Benutzer scheint es schneller zu sein.
quelle
Virtuelles Scrollen ist eine weitere Möglichkeit, die Bildlaufleistung bei großen Listen und großen Datenmengen zu verbessern.
Eine Möglichkeit, dies zu implementieren, ist die Verwendung von Angular Material,
md-virtual-repeat
wie in dieser Demo mit 50.000 Elementen gezeigtEntnommen direkt aus der Dokumentation der virtuellen Wiederholung:
quelle
Eine andere Version @Steffomio
Anstatt jedes Element einzeln hinzuzufügen, können wir Elemente nach Stücken hinzufügen.
quelle
Manchmal, was passiert ist, erhalten Sie die Daten vom Server (oder Back-End) in wenigen ms (ich gehe beispielsweise davon aus, dass es 100 ms sind), aber die Anzeige auf unserer Webseite dauert länger (sagen wir, es dauert 900 ms bis Anzeige).
Was hier passiert, sind 800 ms. Es dauert nur, um eine Webseite zu rendern.
Was ich in meiner Webanwendung getan habe, ist, dass ich Paginierung verwendet habe (oder Sie können unendliches Scrollen verwenden ), um eine Liste von Daten anzuzeigen. Angenommen, ich zeige 50 Daten / Seite.
Ich werde also nicht alle Daten auf einmal laden, sondern nur 50 Daten, die ich anfänglich lade, was nur 50 ms dauert (ich gehe hier davon aus).
Die Gesamtzeit wurde hier von 900 ms auf 150 ms verringert. Sobald der Benutzer die nächste Seite angefordert hat, werden die nächsten 50 Daten angezeigt und so weiter.
Ich hoffe, dies wird Ihnen helfen, die Leistung zu verbessern. Alles Gute
quelle
Dies lädt Daten, wenn es bis zum Ende der Seite reicht und die Hälfte der zuvor geladenen Daten entfernt, und wenn es wieder bis zum oberen Rand des Div reicht. Vorherige Daten (abhängig von der Seitenzahl) werden geladen, wobei die Hälfte der aktuellen Daten entfernt wird. Also auf DOM Zu einem Zeitpunkt sind nur begrenzte Daten vorhanden, was zu einer besseren Leistung führen kann, anstatt ganze Daten beim Laden zu rendern.
HTML QUELLTEXT:
Winkelcode:
Demo mit Direktive
Abhängig von der Höhe der Teilung werden die Daten geladen und beim Scrollen werden neue Daten angehängt und vorherige Daten werden entfernt.
HTML Quelltext:
Winkelcode:
Demo mit UI-Raster mit Infinite-Scroll-Demo
quelle
Für große Datenmengen und Dropdown-Listen mit mehreren Werten ist es besser, diese zu verwenden
ng-options
alsng-repeat
.ng-repeat
ist langsam, da alle kommenden Werte durchlaufen werden, aberng-options
einfach zur Auswahloption angezeigt wird.viel viel schneller als
quelle