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 explores un feed de desplazamiento infinito en tu sitio de redes sociales favorito o que navegues 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 ser lentas para renderizar y navegar , ya que cada elemento de la lista puede tener datos enriquecidos, contenido multimedia y funcionalidad.
Los usuarios pueden experimentar problemas cuando cargan la página o se desplazan por ella, 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 Kit de desarrollo de componentes (CDK) proporciona el desplazamiento virtual. 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 quepan 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 vuelve a usar 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 y funcional en esta app de ejemplo:
Configura 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 un viewport
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 <div>
individuales. Esto puede ser adecuado para los nodos de texto básicos, pero cualquier complejidad en la plantilla repetida no se escala bien, y los objetos de escucha de eventos se multiplicarán de forma significativa.
Para agregar el desplazamiento virtual y evitar esos problemas, debes crear un viewport
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);
}
Debido a que ScrollingModule renderiza de forma dinámica subconjuntos de la lista, debes especificar la altura del viewport con CSS estándar. También debes darle al viewport una sugerencia sobre su contenido especificando el itemSize. El módulo usa esta información para determinar cuántos elementos se deben mantener en el DOM en un momento determinado y cómo renderizar una barra de desplazamiento con el 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, el viewport identifica de forma dinámica el subconjunto correcto de la lista para el usuario y, luego, itera por él. Ahora, cuando el usuario cargue la página, el CDK debería renderizar el subconjunto de la lista que se ajusta a la pantalla (más un poco de búfer), y cualquier evento de desplazamiento en el viewport cargará y renderizará el subconjunto apropiado de la lista:
Ir más allá
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 podría recuperar a pedido para aplicaciones más complejas. Para obtener más información sobre las otras capacidades de
ScrollingModule y la directiva cdkVirtualOf, lee sobre Scrolling
en la documentación de CDK.