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 para explorar un feed de desplazamiento infinito en tu sitio de redes sociales favorito o para navegar 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 de antemano. También pueden ser lentos para renderizar y navegar , ya que cada elemento de la lista puede tener datos enriquecidos, contenido multimedia y funcionalidad.
Los usuarios pueden tener 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 del tamaño adecuado, y la capacidad de navegar por la lista sin que la aplicación tenga que contener toda la lista en la memoria o renderizarla en la página.
En Angular, el desplazamiento virtual se proporciona a través del 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 se ajusten a la pantalla (más un búfer pequeño). A medida que el usuario navega, se calcula y renderiza un nuevo subconjunto de elementos, reutilizando 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 funcional completo 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 simple 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 estar bien para nodos de texto simples, pero cualquier complejidad en la plantilla repetida no se escalará bien y se multiplicarán significativamente los objetos de escucha de eventos.
Para agregar el desplazamiento virtual y evitar esos problemas, debes crear un viewport uniendo 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 subconjuntos de la lista de forma dinámica, debes especificar la altura del viewport con una CSS estándar. También debes proporcionarle una sugerencia sobre su contenido a la vista del viewport especificando itemSize
. El módulo utiliza esta información para determinar la cantidad de elementos que se conservarán en el DOM en un momento determinado y la manera de representar una barra de desplazamiento del 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 identificará e iterará de forma dinámica el subconjunto correcto de la lista para el usuario. 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 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. Para obtener más información sobre las otras funciones de ScrollingModule
y la directiva cdkVirtualOf
, lee sobre Scrolling
en la documentación de CDK.
Hero image de Mr Cup / Fabien Barral en Unsplash.