Mam ogromny zbiór danych obejmujący kilka tysięcy wierszy z około 10 polami każdy, około 2 MB danych. Muszę to wyświetlić w przeglądarce. Najprostsze podejście (pobieranie danych, umieszczanie ich $scope
, ng-repeat=""
wykonywanie swojej pracy) działa dobrze, ale zawiesza przeglądarkę na około pół minuty, gdy zaczyna wstawiać węzły do DOM. Jak mam podejść do tego problemu?
Jedną z opcji jest dodawanie wierszy $scope
przyrostowo i czekanie na ngRepeat
zakończenie wstawiania jednego fragmentu do DOM przed przejściem do następnego. Ale AFAIK ngRepeat nie zgłasza się po zakończeniu „powtarzania”, więc będzie brzydki.
Inną opcją jest podzielenie danych na serwerze na strony i pobranie ich w wielu żądaniach, ale to jeszcze brzydsze.
Przejrzałem dokumentację Angulara w poszukiwaniu czegoś podobnego ng-repeat="data in dataset" ng-repeat-steps="500"
, ale nic nie znalazłem. Jestem dość nowy w sposobach Angulara, więc możliwe, że całkowicie mija się z celem. Jakie są najlepsze praktyki w tym zakresie?
limitTo
do wyświetlenia tylko 20 elementów:<p ng-repeat="data in dataset | limitTo:20">{{data}}</p>
Pokazuje tylko 20 elementów. Następnie możesz użyć stron i pokazać następne 10 elementów lub coś w tym rodzaju. :)Odpowiedzi:
Zgadzam się z @ AndreM96, że najlepszym podejściem jest wyświetlanie tylko ograniczonej liczby wierszy, szybszego i lepszego UX, można to zrobić za pomocą paginacji lub nieskończonego przewijania.
Nieskończone przewijanie z Angular jest naprawdę proste dzięki filtrowi limitTo . Musisz tylko ustawić początkowy limit, a gdy użytkownik prosi o więcej danych (dla uproszczenia używam przycisku), zwiększasz limit.
Oto plik JsBin .
Takie podejście może być problemem w przypadku telefonów, ponieważ zwykle opóźniają się one podczas przewijania dużej ilości danych, więc w tym przypadku myślę, że paginacja pasuje lepiej.
Aby to zrobić, będziesz potrzebować filtra limitTo, a także niestandardowego filtru, aby zdefiniować punkt początkowy wyświetlanych danych.
Oto JSBin z paginacją.
źródło
Najgorętsze - i prawdopodobnie najbardziej skalowalne - podejście do pokonywania tych wyzwań w przypadku dużych zbiorów danych jest zawarte w dyrektywie Ionic CollectionRepeat i innych podobnych implementacjach. Wymyślnym terminem na to jest `` eliminacja okluzji '' , ale można to podsumować następująco: nie ograniczaj liczby renderowanych elementów DOM do dowolnej (ale wciąż wysokiej) liczby z paginami, takiej jak 50, 100, 500 ... zamiast tego , ogranicz tylko do tylu elementów, ile użytkownik widzi .
Jeśli zrobisz coś podobnego do tego, co jest powszechnie znane jako „nieskończone przewijanie”, nieco zmniejszasz początkową liczbę DOM, ale po kilku odświeżeniach szybko się powiększa, ponieważ wszystkie te nowe elementy są po prostu przyczepione na dole. Przewijanie dochodzi do indeksowania, ponieważ przewijanie polega na liczbie elementów. Nie ma w tym nic nieskończonego.
Natomiast
collectionRepeat
podejście polega na użyciu tylko tylu elementów, ile zmieści się w rzutni, a następnie ich przetworzeniu . Gdy jeden element obraca się poza widok, jest odłączany od drzewa renderowania, uzupełniany danymi dla nowego elementu na liście, a następnie ponownie dołączany do drzewa renderowania na drugim końcu listy. Jest to najszybszy znany człowiekowi sposób uzyskiwania nowych informacji do i z DOM, wykorzystujący ograniczony zestaw istniejących elementów, zamiast tradycyjnego cyklu tworzenia / niszczenia ... tworzenia / niszczenia. Korzystając z tego podejścia, możesz naprawdę zaimplementować nieskończone przewijanie.Zwróć uwagę, że nie musisz używać Ionic, aby używać / hack / adapt
collectionRepeat
, ani żadnego innego podobnego narzędzia. Dlatego nazywają to open-source. :-) (To powiedziawszy, zespół Ionic robi całkiem genialne rzeczy, warte twojej uwagi.)Jest przynajmniej jeden doskonały przykład robienia czegoś bardzo podobnego w Reakcie. Tylko zamiast przetwarzać elementy ze zaktualizowaną zawartością, po prostu decydujesz się nie renderować niczego w drzewie, czego nie ma w widoku. Błyskawicznie działa na 5000 pozycji, chociaż ich bardzo prosta implementacja POC pozwala na odrobinę migotania ...
Ponadto ... aby powtórzyć niektóre inne posty, użycie
track by
jest bardzo pomocne, nawet w przypadku mniejszych zbiorów danych. Uważaj to za obowiązkowe.źródło
Polecam to zobaczyć:
Optymalizacja AngularJS: 1200 ms do 35 ms
stworzyli nową dyrektywę, optymalizując powtarzanie ng w 4 częściach:
projekt jest tutaj na github:
Stosowanie:
1- Uwzględnij te pliki w swojej aplikacji jednostronicowej:
2- Dodaj zależność od modułu:
3- wymień ng-powtórz
Cieszyć się!
źródło
sly-repeat
ale nic mi nie pomogło, wyniki są nadal powolne, a przeglądarka opóźnia się również z naruszeniami[Violation] 'setTimeout' handler took 54ms
,[Violation] 'scroll' handler took 1298ms
Oprócz wszystkich powyższych wskazówek, takich jak track by i mniejsze pętle, ta również bardzo mi pomogła
ten fragment kodu wypisze nazwę po załadowaniu i przestanie go oglądać. Podobnie, dla powtórzeń ng, można go użyć jako
jednak działa tylko z AngularJS w wersji 1.3 i nowszych. Z http://www.befundoo.com/blog/optimizing-ng-repeat-in-angularjs/
źródło
::
powtórzenia, jak i wyrażenia? Doktorzy mówią inaczej, ale nie jestem pewien sposobu sprawdzenia, czy to działa. docs.angularjs.org/guide/expressionAby zwiększyć wydajność, możesz użyć funkcji „śledź według”:
Szybszy niż:
ref: https://www.airpair.com/angularjs/posts/angularjs-performance-large-applications
źródło
Jeśli wszystkie twoje wiersze mają równą wysokość, zdecydowanie powinieneś przyjrzeć się wirtualizacji ng-repeat: http://kamilkp.github.io/angular-vs-repeat/
To demo wygląda bardzo obiecująco (i obsługuje przewijanie inercyjne)
źródło
Zasada nr 1: Nigdy nie pozwól użytkownikowi czekać na nic.
Mając to na uwadze, strona rozwijająca się, która potrzebuje 10 sekund, pojawia się znacznie szybciej niż czekanie 3 sekundy na pusty ekran i otrzymanie wszystkiego naraz.
Zamiast więc przyspieszać stronę, po prostu pozwól, aby strona wyglądała na szybką, nawet jeśli wynik końcowy jest wolniejszy:
Powyższy kod sprawia, że lista rośnie wiersz po wierszu i jest zawsze wolniejsza niż renderowanie wszystkich naraz. Ale dla użytkownika wydaje się to być szybsze.
źródło
Wirtualne przewijanie to kolejny sposób na poprawę wydajności przewijania w przypadku ogromnych list i dużych zbiorów danych.
Jednym ze sposobów realizacji tego jest użycie Angular Material,
md-virtual-repeat
jak pokazano w tym Demo z 50000 elementamiZaczerpnięte prosto z dokumentacji wirtualnej powtórki:
źródło
Inna wersja @Steffomio
Zamiast dodawać każdy element osobno, możemy dodawać elementy fragmentami.
źródło
Czasami co się stało, otrzymujesz dane z serwera (lub zaplecza) w ciągu kilku ms (na przykład zakładam, że to 100 ms), ale wyświetlenie na naszej stronie zajmuje więcej czasu (powiedzmy, że trwa 900 aby pokaz).
Tak więc to, co się tutaj dzieje, to 800 ms. Wystarczy wyrenderować stronę internetową.
To, co zrobiłem w mojej aplikacji internetowej, to użycie paginacji (lub możesz użyć nieskończonego przewijania ) do wyświetlenia listy danych. Powiedzmy, że wyświetlam 50 danych na stronę.
Więc nie będę ładował wszystkich danych na raz, tylko 50 danych, które ładuję początkowo, co zajmuje tylko 50 ms (zakładam tutaj).
więc całkowity czas tutaj zmniejszył się z 900 ms do 150 ms, gdy użytkownik zażąda następnej strony, a następnie wyświetli następne 50 danych i tak dalej.
Mam nadzieję, że pomoże to poprawić wydajność. Wszystkiego najlepszego
źródło
który ładuje dane, gdy osiągnie dół strony i usuwa połowę wcześniej załadowanych danych, a gdy ponownie osiąga górę div, zostaną załadowane poprzednie dane (w zależności od numeru strony) usuwając połowę bieżących danych Tak na DOM w danym momencie obecne są tylko ograniczone dane, co może prowadzić do lepszej wydajności zamiast renderowania całych danych pod obciążeniem.
KOD HTML:
Kątowy KOD:
Demo z dyrektywą
W zależności od wysokości podziału ładuje dane i po przewinięciu nowe dane zostaną dołączone, a poprzednie zostaną usunięte.
Kod HTML:
Kod kątowy:
Demo z siatką UI z nieskończonym przewijaniem Demo
źródło
w przypadku dużego zestawu danych i listy rozwijanej wielu wartości lepiej jest użyć
ng-options
zamiastng-repeat
.ng-repeat
jest powolny, ponieważ zapętla wszystkie nadchodzące wartości, aleng-options
po prostu wyświetla się w opcji wyboru.znacznie szybciej niż
źródło