DEV Community

Cover image for trackByF: Optimizando nuestras listas en Angular
Ricardo Arana Reyes Guerrero
Ricardo Arana Reyes Guerrero

Posted on • Updated on

trackByF: Optimizando nuestras listas en Angular

Mientras preparaba mi clase para el curso de angular que para la capacitación de personal en la empresa donde trabajo. Me puse a revisar detenidamente la documentación de ngFor, algo tan banal y simple que nunca falta en un proyecto angular. Y me di cuenta que había un atributo que nunca había usado o percatado de su existencia, el “track by”.
Cuando actualizamos una propiedad en nuestro componente este dispara en property binding haciendo que la template se reescriba con la nueva lista, pero mucho ojo! No es que agregue nuevos elementos si no lo que pasa es que limpia todo los elementos en el dom y los vuelve a escribir, si bien en una lista pequeña esto no importa mucho, si la cantidad de elementos es grande o el objeto iterado tiene muchas propiedades puede traer problemas en performance de la aplicación.
Ahora necesitamos algo importante para que angular pueda trabajar correctamente nuestra lista, y es que cada elemento tenga un identificador único, de esa forma angular sabrá qué objetos son nuevos en a lista y cuales ya los tienes impresos.
mucho cuchicheo, vamos con el ejemplo!

Mi lista de compras

Bien digamos que tengo una aplicación simple que tiene mi lista de compras del super(de verdad tengo que hacer compras este finde).
Y tenemos un botón que lo que hace es cambiar la lista por una idéntica! pero con 2 elementos nuevos.
Alt Text
Veamos que hay en el código

app.component.ts

import { Component, VERSION } from '@angular/core';
import { Item } from './models/item.model';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  lista: Item[] = []

  constructor() {
    this.lista = [
      {id: '1', desc: 'Ajos'},
      {id: '2', desc: 'Tomates'},
      {id: '3', desc: 'Papas'},
      {id: '4', desc: 'Cebollas'},
    ];
  }

  actualizar() {
    this.lista = [
      {id: '1', desc: 'Ajos'},
      {id: '2', desc: 'Tomates'},
      {id: '3', desc: 'Papas'},
      {id: '4', desc: 'Cebollas'},
      {id: '5', desc: 'mostaza'},
      {id: '6', desc: 'Mayonesa'},
    ];
  }
}
Enter fullscreen mode Exit fullscreen mode

app.component.html

<h1>Lista de compras</h1>
<button (click)="actualizar()"> Actualizar </button>
<ul>
  <li *ngFor="let item of lista">{{ item.desc }}</li>
</ul>
Enter fullscreen mode Exit fullscreen mode

Al presionar el botón vemos que se reescribe toda la lista
Alt Text

Como podemos con el tooldev de chrome vemos que todos los elemento está volviendo a reescribirse a pesar de que la lista solo agrega 2 elementos nuevos.
Ahora vamos a crear un método el cual indiquemos cual como pueden identificar como único los elementos de la lista.

trackByFn(index: number, item: Item) {
return item.id;
}
Enter fullscreen mode Exit fullscreen mode

el primer parámetro es el índice del elemento y el segundo es el propio elemento, lo que debe retornar nuestra función es cual es la propiedad o identificador que hace único a ese elemento de la lista. En este caso nuestro caso la propiedad “id”.
Ahora le indicamos a nuestro ngFor que esta es la trackby
y magia!

Alt Text

Como vemos resaltado en morado, lo único que se escribió en el DOM fueron los 2 nuevos elementos, dándole un mejor rendimiento a nuestra aplicación.
Ahora manos a la obra y optimiza tus ngFor, no olvides apoyarme con unas palmaditas.
Puede seguirme en youtube tambien tengo unos cuantos tutoriales.
https://www.youtube.com/channel/UCVXDZUMTSPpM8tVCjiXnz7Q
Aquí tiene el código!

Top comments (2)

Collapse
 
alexisnarvaez97 profile image
Alexis E. Narvaez Tadeo.

¿Sirve también para cuando usas observables con el pipe | async? me surgió esa duda.

Collapse
 
ricardoarana profile image
Ricardo Arana Reyes Guerrero

Si, también funciona con el pipe Async, mira este ejemplo

stackblitz.com/edit/trackby-obs?fi...