J'ai un énorme ensemble de données de plusieurs milliers de lignes avec environ 10 champs chacun, environ 2 Mo de données. J'ai besoin de l'afficher dans le navigateur. L'approche la plus simple (récupérer des données, les insérer $scope
, laisser ng-repeat=""
faire son travail) fonctionne bien, mais elle gèle le navigateur pendant environ une demi-minute lorsqu'il commence à insérer des nœuds dans DOM. Comment dois-je aborder ce problème?
Une option consiste à ajouter des lignes de manière $scope
incrémentielle et d'attendre la ngRepeat
fin de l'insertion d'un morceau dans le DOM avant de passer au suivant. Mais AFAIK ngRepeat ne rend pas compte quand il a fini de "répéter", donc ça va être moche.
Une autre option consiste à diviser les données sur le serveur en pages et à les récupérer en plusieurs requêtes, mais c'est encore plus laid.
J'ai parcouru la documentation Angular à la recherche de quelque chose comme ng-repeat="data in dataset" ng-repeat-steps="500"
, mais je n'ai rien trouvé. Je suis assez nouveau dans les méthodes angulaires, il est donc possible que je manque complètement le point. Quelles sont les meilleures pratiques à ce sujet?
limitTo
pour afficher seulement 20 éléments:<p ng-repeat="data in dataset | limitTo:20">{{data}}</p>
Cela montre seulement 20 éléments. Ensuite, vous pouvez utiliser des pages et afficher les 10 éléments suivants ou quelque chose comme ça. :)Réponses:
Je suis d'accord avec @ AndreM96 que la meilleure approche consiste à n'afficher qu'un nombre limité de lignes, une UX plus rapide et meilleure, cela pourrait être fait avec une pagination ou avec un défilement infini.
Le défilement infini avec Angular est vraiment simple avec le filtre limitTo . Il vous suffit de définir la limite initiale et lorsque l'utilisateur demande plus de données (j'utilise un bouton pour plus de simplicité), vous incrémentez la limite.
Voici un JsBin .
Cette approche pourrait être un problème pour les téléphones car ils sont généralement à la traîne lors du défilement de beaucoup de données, donc dans ce cas, je pense qu'une pagination convient mieux.
Pour ce faire, vous aurez besoin du filtre limitTo et également d'un filtre personnalisé pour définir le point de départ des données affichées.
Voici un JSBin avec une pagination.
la source
L'approche la plus chaude - et sans doute la plus évolutive - pour surmonter ces défis avec de grands ensembles de données est incarnée par l'approche de la directive collectionRepeat d' Ionic et d'autres implémentations similaires. Un terme sophistiqué pour cela est `` culling d'occlusion '' , mais vous pouvez le résumer comme suit: ne limitez pas simplement le nombre d'éléments DOM rendus à un nombre paginé arbitraire (mais toujours élevé) comme 50, 100, 500 ... , limitez-vous à autant d'éléments que l'utilisateur peut voir .
Si vous faites quelque chose comme ce que l'on appelle communément le "défilement infini", vous réduisez quelque peu le nombre initial de DOM, mais il gonfle rapidement après quelques rafraîchissements, car tous ces nouveaux éléments sont simplement cloués en bas. Le défilement est une analyse, car le défilement est une question de nombre d'éléments. Il n'y a rien d'infini à ce sujet.
Tandis que l'
collectionRepeat
approche consiste à n'utiliser que le nombre d'éléments pouvant tenir dans la fenêtre, puis à les recycler . Lorsqu'un élément tourne hors de la vue, il est détaché de l'arborescence de rendu, rempli de données pour un nouvel élément dans la liste, puis rattaché à l'arborescence de rendu à l'autre extrémité de la liste. C'est le moyen le plus rapide connu de l'homme pour obtenir de nouvelles informations dans et hors du DOM, en utilisant un ensemble limité d'éléments existants, plutôt que le cycle traditionnel de création / destruction ... création / destruction. En utilisant cette approche, vous pouvez vraiment implémenter un défilement infini .Notez que vous n'avez pas besoin d'utiliser Ionic pour utiliser / hack / adapt
collectionRepeat
, ou tout autre outil similaire. C'est pourquoi ils l'appellent open-source. :-) (Cela dit, l'équipe Ionic fait des choses assez ingénieuses, dignes de votre attention.)Il y a au moins un excellent exemple de quelque chose de très similaire dans React. Seulement au lieu de recycler les éléments avec un contenu mis à jour, vous choisissez simplement de ne pas rendre quoi que ce soit dans l'arborescence qui n'est pas visible. C'est extrêmement rapide sur 5000 éléments, bien que leur implémentation POC très simple permette un peu de scintillement ...
Aussi ... pour faire écho à certains des autres articles, l'utilisation
track by
est très utile, même avec des ensembles de données plus petits. Considérez cela comme obligatoire.la source
Je recommande de voir ceci:
Optimisation d'AngularJS: 1200 ms à 35 ms
ils ont fait une nouvelle directive en optimisant ng-repeat en 4 parties:
le projet est ici sur github:
Usage:
1- Incluez ces fichiers dans votre application monopage:
2- Ajouter une dépendance de module:
3- remplacer ng-repeat
Prendre plaisir!
la source
sly-repeat
mais rien ne m'a aidé, les résultats sont toujours lents et le navigateur retarde également les violations[Violation] 'setTimeout' handler took 54ms
,[Violation] 'scroll' handler took 1298ms
En plus de tous les conseils ci-dessus, comme la piste par et les boucles plus petites, celui-ci m'a également beaucoup aidé
ce morceau de code afficherait le nom une fois qu'il a été chargé, et arrêterait de le regarder après cela. De même, pour ng-repeats, il pourrait être utilisé comme
cependant cela ne fonctionne que pour AngularJS version 1.3 et supérieure. De http://www.befundoo.com/blog/optimizing-ng-repeat-in-angularjs/
la source
::
de la répétition ainsi que de l'expression? La documentation dit le contraire, mais je ne suis pas sûr de savoir si cela fonctionne. docs.angularjs.org/guide/expressionVous pouvez utiliser "track by" pour augmenter les performances:
Plus rapide que:
réf: https://www.airpair.com/angularjs/posts/angularjs-performance-large-applications
la source
Si toutes vos lignes ont la même hauteur, vous devez absolument jeter un œil à la virtualisation ng-repeat: http://kamilkp.github.io/angular-vs-repeat/
Cette démo semble très prometteuse (et elle prend en charge le défilement inertiel)
la source
Règle n ° 1: ne laissez jamais l'utilisateur attendre quoi que ce soit.
Cela à l'esprit qu'une page en pleine croissance qui a besoin de 10 secondes apparaît bien plus rapidement que d'attendre 3 secondes devant un écran vide et d'obtenir tout en même temps.
Donc, au lieu de rendre la page rapide, laissez simplement la page paraître rapide, même si le résultat final est plus lent:
Le code ci-dessus laisse apparaître la liste pour croître ligne par ligne, et est toujours plus lent que le rendu en une seule fois. Mais pour l'utilisateur, cela semble être plus rapide.
la source
Défilement virtuel est un autre moyen d'améliorer les performances de défilement lors du traitement de listes volumineuses et d'un ensemble de données volumineux.
Une façon de l'implémenter consiste à utiliser le matériau angulaire
md-virtual-repeat
comme il est démontré dans cette démo avec 50000 élémentsTiré directement de la documentation de la répétition virtuelle:
la source
Une autre version @Steffomio
Au lieu d'ajouter chaque élément individuellement, nous pouvons ajouter des éléments par morceaux.
la source
Parfois, ce qui s'est passé, vous obtenez les données du serveur (ou du back-end) en quelques ms (par exemple, je suppose que cela prend 100 ms ) mais cela prend plus de temps à s'afficher sur notre page Web (disons que cela prend 900 ms pour afficher).
Donc, ce qui se passe ici est de 800 ms. Il suffit de rendre la page Web.
Ce que j'ai fait dans mon application Web, c'est que j'ai utilisé la pagination (ou vous pouvez également utiliser le défilement infini ) pour afficher la liste des données. Disons que je montre 50 données / page.
Je ne chargerai donc pas le rendu de toutes les données à la fois, seulement 50 données que je charge initialement, ce qui ne prend que 50 ms (je suppose ici).
donc le temps total ici a diminué de 900 ms à 150 ms, une fois que l'utilisateur demande la page suivante, puis affiche les 50 données suivantes et ainsi de suite.
J'espère que cela vous aidera à améliorer les performances. Bonne chance
la source
qui charge les données quand il atteint le bas de la page et supprime la moitié des données précédemment chargées et quand il atteint le haut de la div à nouveau les données précédentes (en fonction du numéro de page) seront chargées en supprimant la moitié des données actuelles Donc sur DOM à la fois, seules des données limitées sont présentes, ce qui peut conduire à de meilleures performances au lieu de restituer des données entières en charge.
CODE HTML:
CODE angulaire:
Démo avec directive
En fonction de la hauteur de la division, il charge les données et lors du défilement, de nouvelles données seront ajoutées et les données précédentes seront supprimées.
Code HTML:
Code angulaire:
Démo avec grille d'interface utilisateur avec démo à défilement infini
la source
pour un ensemble de données volumineux et une liste déroulante de valeurs multiples, il est préférable d'utiliser
ng-options
plutôt queng-repeat
.ng-repeat
est lent car il boucle sur toutes les valeurs à venir maisng-options
affiche simplement l'option de sélection.beaucoup plus vite que
la source