Tengo un gran conjunto de datos de varios miles de filas con alrededor de 10 campos cada una, aproximadamente 2 MB de datos. Necesito mostrarlo en el navegador. El enfoque más sencillo (buscar datos, ponerlo $scope
, dejar que ng-repeat=""
haga su trabajo) funciona bien, pero congela el navegador durante aproximadamente medio minuto cuando comienza a insertar nodos en DOM. ¿Cómo debo abordar este problema?
Una opción es agregar filas de forma $scope
incremental y esperar a ngRepeat
que termine de insertar un fragmento en DOM antes de pasar al siguiente. Pero AFAIK ngRepeat no informa cuando termina de "repetirse", por lo que será feo.
Otra opción es dividir los datos del servidor en páginas y buscarlos en múltiples solicitudes, pero eso es aún más feo.
Miré a través de la documentación angular en busca de algo así ng-repeat="data in dataset" ng-repeat-steps="500"
, pero no encontré nada. Soy bastante nuevo en las formas angulares, por lo que es posible que me esté perdiendo el punto por completo. ¿Cuáles son las mejores prácticas en esto?
limitTo
para mostrar solo 20 elementos:<p ng-repeat="data in dataset | limitTo:20">{{data}}</p>
esto muestra solo 20 elementos. Luego, podría usar páginas y mostrar los siguientes 10 elementos o algo así. :)Respuestas:
Estoy de acuerdo con @ AndreM96 en que el mejor enfoque es mostrar solo una cantidad limitada de filas, UX más rápido y mejor, esto podría hacerse con una paginación o con un desplazamiento infinito.
El desplazamiento infinito con Angular es realmente simple con limitTo filter. Solo tiene que establecer el límite inicial y cuando el usuario solicita más datos (estoy usando un botón para simplificar), incrementa el límite.
Aquí hay un JsBin .
Este enfoque podría ser un problema para los teléfonos porque generalmente se retrasan al desplazar una gran cantidad de datos, por lo que en este caso creo que una paginación encaja mejor.
Para hacerlo, necesitará el filtro limitTo y también un filtro personalizado para definir el punto de partida de los datos que se muestran.
Aquí hay un JSBin con una paginación.
fuente
El enfoque más popular, y posiblemente el más escalable, para superar estos desafíos con grandes conjuntos de datos se materializa en el enfoque de la directiva collectionRepeat de Ionic y en otras implementaciones similares. Un término elegante para esto es 'eliminación de oclusiones' , pero puede resumirlo como: no limite el recuento de elementos DOM representados a un número arbitrario (pero aún alto) paginado como 50, 100, 500 ... en su lugar , limite solo a tantos elementos como el usuario pueda ver .
Si hace algo como lo que comúnmente se conoce como "desplazamiento infinito", está reduciendo un poco el conteo inicial de DOM, pero se hincha rápidamente después de un par de actualizaciones, porque todos esos elementos nuevos se agregan en la parte inferior. El desplazamiento se arrastra, porque el desplazamiento se trata de contar elementos. No hay nada infinito al respecto.
Mientras que, el
collectionRepeat
enfoque es usar solo tantos elementos como quepan en la ventana gráfica, y luego reciclarlos . A medida que un elemento gira fuera de la vista, se separa del árbol de representación, se vuelve a llenar con datos para un nuevo elemento en la lista y luego se vuelve a unir al árbol de representación en el otro extremo de la lista. Esta es la forma más rápida conocida por el hombre para obtener nueva información dentro y fuera del DOM, haciendo uso de un conjunto limitado de elementos existentes, en lugar del ciclo tradicional de crear / destruir ... crear / destruir. Con este enfoque, realmente puede implementar un desplazamiento infinito .Tenga en cuenta que no tiene que usar Ionic para usar / piratear / adaptar
collectionRepeat
, ni ninguna otra herramienta como esta. Por eso lo llaman de código abierto. :-) (Dicho esto, el equipo de Ionic está haciendo algunas cosas bastante ingeniosas, dignas de su atención).Hay al menos un excelente ejemplo de hacer algo muy similar en React. Solo que en lugar de reciclar los elementos con contenido actualizado, simplemente elige no representar nada en el árbol que no esté a la vista. Es increíblemente rápido en 5000 artículos, aunque su implementación POC muy simple permite un poco de parpadeo ...
Además ... para hacer eco de algunas de las otras publicaciones, el uso
track by
es muy útil, incluso con conjuntos de datos más pequeños. Considéralo obligatorio.fuente
Recomiendo ver esto:
Optimizando AngularJS: 1200ms a 35ms
hicieron una nueva directiva al optimizar ng-repeat en 4 partes:
el proyecto está aquí en github:
Uso:
1- incluye estos archivos en tu aplicación de una sola página:
2- agregar dependencia de módulo:
3- reemplazar ng-repeat
¡Disfrutar!
fuente
sly-repeat
pero nada me ayudó, los resultados aún son lentos y los retrasos del navegador también reciben violaciones[Violation] 'setTimeout' handler took 54ms
,[Violation] 'scroll' handler took 1298ms
Además de todos los consejos anteriores, como el seguimiento y los bucles más pequeños, este también me ayudó mucho
este código imprimirá el nombre una vez que se haya cargado y dejará de verlo después de eso. Del mismo modo, para ng-repeats, podría usarse como
sin embargo, solo funciona para AngularJS versión 1.3 y superior. De http://www.befundoo.com/blog/optimizing-ng-repeat-in-angularjs/
fuente
::
repetición como la expresión? Los documentos dicen lo contrario, pero no estoy seguro de cómo probar que esto está funcionando. docs.angularjs.org/guide/expressionPuede usar "seguimiento por" para aumentar el rendimiento:
Más rápido que:
ref: https://www.airpair.com/angularjs/posts/angularjs-performance-large-applications
fuente
Si todas sus filas tienen la misma altura, definitivamente debería echar un vistazo a la virtualización ng-repeat: http://kamilkp.github.io/angular-vs-repeat/
Esta demostración parece muy prometedora (y admite desplazamiento inercial)
fuente
Regla No.1: Nunca permita que el usuario espere nada.
Teniendo en cuenta que una página de crecimiento vital que necesita 10 segundos aparece mucho más rápido que esperar 3 segundos antes de una pantalla en blanco y obtener todo a la vez.
Entonces, en lugar de hacer que la página sea rápida, simplemente deje que la página parezca rápida, incluso si el resultado final es más lento:
El código anterior permite que la lista crezca fila por fila, y siempre es más lenta que renderizar de una vez. Pero para el usuario parece ser más rápido.
fuente
Desplazamiento virtual es otra forma de mejorar el rendimiento del desplazamiento cuando se trata de grandes listas y grandes conjuntos de datos.
Una forma de implementar esto es mediante el uso de material angular
md-virtual-repeat
como se demuestra en esta demostración con 50,000 artículosTomado directamente de la documentación de la repetición virtual:
fuente
Otra versión @Steffomio
En lugar de agregar cada elemento individualmente, podemos agregar elementos por partes.
fuente
A veces, lo que sucedió, obtienes los datos del servidor (o back-end) en pocos ms (por ejemplo, supongo que son 100 ms), pero lleva más tiempo mostrarlos en nuestra página web (supongamos que tarda 900 ms en monitor).
Entonces, lo que está sucediendo aquí es de 800 ms. Solo se necesita para mostrar la página web.
Lo que he hecho en mi aplicación web es que he usado la paginación (o puede usar el desplazamiento infinito también) para mostrar la lista de datos. Digamos que estoy mostrando 50 datos / página.
Por lo tanto, no cargaré renderizar todos los datos a la vez, solo 50 datos que estoy cargando inicialmente, lo que toma solo 50 ms (supongo que aquí).
así que el tiempo total aquí disminuyó de 900ms a 150ms, una vez que el usuario solicita la siguiente página, luego muestra los siguientes 50 datos y así sucesivamente.
Espero que esto te ayude a mejorar el rendimiento. Todo lo mejor
fuente
que carga los datos cuando llega al final de la página y elimina la mitad de los datos cargados previamente y cuando llega a la parte superior del div nuevamente, los datos anteriores (dependiendo del número de página) se cargarán eliminando la mitad de los datos actuales. a la vez, solo hay datos limitados, lo que puede conducir a un mejor rendimiento en lugar de representar datos completos en carga.
CÓDIGO HTML:
CÓDIGO angular:
Demo con directiva
Dependiendo de la altura de la división, carga los datos y, al desplazarse, se agregarán nuevos datos y se eliminarán los datos anteriores.
Código HTML:
Código angular:
Demostración con cuadrícula de IU con demostración de desplazamiento infinito
fuente
para el gran conjunto de datos y la caída de valor múltiple hacia abajo, es mejor utilizar
ng-options
en lugar deng-repeat
.ng-repeat
es lento porque recorre todos los valores que vienen, perong-options
simplemente se muestra en la opción de selección.mucho más rápido que
fuente