[Xamarin.Forms] Optimizando listados con estrategias de cacheo

JumpListXamarin.Forms 2.0

Con la llegada de Xamarin 4 han aterrizado una gran cantidad de diversas novedades entre las que destaca la versión 2.0 de Xamarin Forms. Entre las novedades principales contamos con:

  • Soporte a UWP.
  • Compilación de XAML (XAMLC).
  • Optimización en Layouts.
  • Optimización de listados. Incluidas nuevas estrategias de cacheo.
  • Corrección de bugs.

Optimizando listados

Entre el listado de controles fundamentales de cualquier aplicación, junto a textos, cajas de textos y botones, destacaríamos los listados. Es un control muy habitual en la inmensa mayoría de aplicaciones.

Como hemos visto en el listado de novedades de Xamarin.Forms 2.0, se han introducido mejoras en el rendimiento del control listView incluyendo nuevas estrategias de cacheo.

Estrategias de cacheo

A menudo, en listados debemos soportar grandes cantidades de elementos muy superiores a lo que se puede mostrar en pantalla e incluso a lo que se puede alcanzar con un ligero scroll. Esto impacta negativamente en el rendimiento. Tanto en iOS como en Android contamos con mecanismos de reciclado de celdas que permiten solucionar o mitigar este problema. La técnica consiste en contar solo en memoria con una pequeña cantidad de celdas en memoria de modo que se van reciclando y reutilizando elementos según el usuario realiza scroll.

Con la llegada de Xamarin.Forms 2.0 podemos aprovechar estas características nativas desde Forms. El control ListView recibe una nueva propiedad llamada CachingStrategy para esteblecer el tipo de cacheo realizado. Soporta uno de los siguientes valores:

  • RetainElement: Comportamiento por defecto. Genera una celda diferente por cada elemento del listado. Es recomendable su uso en caso de gran cantidad de cambios en el contexto. Sin embargo, hay que tener en cuenta que el código de inicialización de cada celda se ejecutará por cada celda pudiendo afectar al rendimiento.
  • RecycleElement: Esta opción toma ventajas de los mecanismos nativos de iOS y Android para el reciclado de celdas. Recomendable su uso cuando las celdas no tienen grandes cambios de contexto y su layout es similar. Reduce el consumo de memoria y la rapidez de uso.

Para realizar pruebas de rendimiento, crearemos un sencillo ejemplo con un listado con un número elevado de elementos (monos). En nuestra ViewModel creamos un listado:

[sourcecode language="vb"]
public ObservableCollection<Monkey> Monkeys
{
     get { return _monkeys; }
     set
     {
          _monkeys = value;
          RaisePropertyChanged();
     }
}
[/sourcecode]

Creamos un listado aleatorio de 1000 elementos:

[sourcecode language="vb"]
_count = 1;
Random random = new Random();
for (int i = 0; i < 1000; i++)
{
     Monkeys.Insert(0,
          new Monkey
          {
               Name = string.Format("Monkey {0}", _count),
               Location = Countries[random.Next(0, Countries.Count)],
               Photo = Images[random.Next(0, Images.Count)]
          });
     _count++;
}
[/sourcecode]

En la interfaz, utilizamos el control ListView utilizando el reciclado de celdas:

[sourcecode language="vb"]
<ListView
     ItemsSource="{Binding Monkeys}"
     CachingStrategy="RecycleElement">
     <ListView.ItemTemplate>
      <DataTemplate>
        <ViewCell>
          <StackLayout Orientation="Vertical">
            <StackLayout Orientation="Horizontal">
              <Image Source="{Binding Photo}"
                     Aspect="AspectFill"
                     WidthRequest="100"/>
              <Label Text="{Binding Name}"
                     VerticalOptions="Center"/>
              <Label Text="{Binding Location}"
                     HorizontalOptions="EndAndExpand"
                     VerticalOptions="Center"/>
            </StackLayout>
          </StackLayout>
        </ViewCell>
      </DataTemplate>
     </ListView.ItemTemplate>
</ListView>
[/sourcecode]

El resultado:

Reciclando celdas
Reciclando celdas

Tenéis el código fuente disponible en GitHub:

Ver GitHub

Recordad que podéis dejar cualquier comentario, sugerencia o duda en los comentarios.

Más información

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *