Implementa el desplazamiento virtual para que las listas grandes sean más responsivas.
La lista de desplazamiento es uno de los patrones de IU más comunes en la actualidad, ya sea que se trate de navegar por un feed de desplazamiento infinito en tu sitio de redes sociales favorito o por un panel empresarial. Cuando las listas de desplazamiento se vuelven muy largas (cientos, miles o cientos de miles de elementos), el rendimiento de la aplicación puede verse afectado.
Las listas grandes pueden tardar en cargarse porque la aplicación debe cargar y renderizar todos los datos por adelantado. También pueden tardar en renderizarse y navegarse porque cada elemento de la lista puede tener datos enriquecidos, contenido multimedia y funcionalidad.
Los usuarios pueden experimentar problemas cuando cargan o se desplazan por la página, lo que genera frustración y abandono de la página.
Desplazamiento virtual en Angular con el kit de desarrollo de componentes
El desplazamiento virtual es la técnica principal que se usa para abordar estos problemas de escala. El desplazamiento virtual da la impresión de una lista muy grande, ya que proporciona una barra de desplazamiento de tamaño adecuado y la capacidad de navegar por la lista sin requerir que la aplicación mantenga toda la lista en la memoria o la renderice en la página.
En Angular, el desplazamiento virtual lo proporciona el kit de desarrollo de componentes (CDK). Si modificas la forma en que iteras por las listas y proporcionas un par de parámetros de configuración adicionales, el desplazamiento virtual del CDK administrará automáticamente la renderización virtual de tus listas, lo que mejorará el rendimiento y la capacidad de respuesta de la página.
En lugar de renderizar toda la lista a la vez, solo se renderizará un subconjunto de los elementos que caben en la pantalla (más un pequeño búfer). A medida que el usuario navega, se calcula y renderiza un nuevo subconjunto de elementos, y se reutiliza el DOM existente si se desea.
En el resto de esta publicación, se explica cómo configurar el desplazamiento virtual básico. Puedes ver un ejemplo completo en esta app de muestra:
Cómo configurar el desplazamiento virtual
Primero, asegúrate de haber instalado @angular/cdk con tu administrador de paquetes favorito. Para instalarlo con npm, ejecuta este comando en la terminal:
npm install --save @angular/cdk
Agrega ScrollingModule a tu app
Con el CDK instalado, importa ScrollingModule, que controla el desplazamiento virtual, desde el paquete @angular/cdk/scrolling. Luego, agrégalo al array de importaciones de tu módulo:
import {ScrollingModule} from '@angular/cdk/scrolling';
...
imports: [
ScrollingModule
...
]
...
Crea una ventana gráfica
Para ver cómo funciona el paquete, intenta crear un componente con una lista de números del 0 al 99,999:
@Component({
template: `<div *ngFor="let item of list">{{item}}</div>`
})
export class ScrollComponent {
list = Array.from({length: 100000}).map((_, i) => i);
}
Cuando el navegador renderiza la app, debe renderizar 100,000 elementos individuales <div>. Esto puede ser adecuado para nodos de texto básicos, pero cualquier complejidad en la plantilla repetida no se adapta bien, y los objetos de escucha de eventos se multiplicarán de manera significativa.
Para agregar desplazamiento virtual y evitar esos problemas, debes crear una ventana gráfica
envolviendo la lista en un elemento <cdk-virtual-scroll-viewport>:
@Component({
template: `<cdk-virtual-scroll-viewport>
<div *ngFor="let item of list">{{item}}</div>
</cdk-virtual-scroll-viewport>`
})
export class ScrollComponent {
list = Array.from({length: 100000}).map((_, i) => i);
}
Dado que ScrollingModule renderiza de forma dinámica subconjuntos de la lista, debes especificar la altura de la ventana gráfica con CSS estándar. También debes darle a la ventana gráfica una sugerencia sobre su contenido especificando el itemSize. El módulo usa esta información para determinar cuántos elementos mantener en el DOM en un momento determinado y cómo renderizar una barra de desplazamiento de tamaño adecuado.
@Component({
template: `<cdk-virtual-scroll-viewport itemSize="18" style="height:80vh">
<div *ngFor="let item of list">{{item}}</div>
</cdk-virtual-scroll-viewport>`
})
export class ScrollComponent {
list = Array.from({length: 100000}).map((_, i) => i);
}
Por último, convierte *ngFor en *cdkVirtualFor:
@Component({
template: `<cdk-virtual-scroll-viewport itemSize="18" style="height:80vh">
<div *cdkVirtualFor="let item of list">{{item}}</div>
</cdk-virtual-scroll-viewport>`
})
export class ScrollComponent {
list = Array.from({length: 100000}).map((_, i) => i);
}
En lugar de iterar por toda la lista, la ventana gráfica identifica de forma dinámica el subconjunto correcto de la lista para el usuario y lo itera. Ahora, cuando el usuario carga la página, el CDK debe renderizar el subconjunto de la lista que cabe en la pantalla (más un poco de búfer), y cualquier evento de desplazamiento en la ventana gráfica carga y renderiza el subconjunto adecuado de la lista:
Más información
Las capacidades de desplazamiento virtual del CDK van mucho más allá de este ejemplo básico. En la app de ejemplo, toda la lista estaba en la memoria, pero se podía recuperar a pedido para aplicaciones más complejas. Puedes obtener más información sobre las otras capacidades de
ScrollingModule y la directiva cdkVirtualOf leyendo sobre Scrolling
en la documentación del CDK.