Lazy Stacks en SwiftUI

Cuando estamos creando una vista dentro de la cual incluimos un listado, ya sea vertical o horizontal, lo normal es utilizar un VStack o un HStack que nos posicionan los hijos de este componente en forma vertical o horizontal respectivamente.

Así, un ejemplo de un listado vertical típico sería tal que así:

var body: some View {
        
        ScrollView{
            VStack{
                ForEach(1...1000, id: \.self) { value  in
                    Text("Row \(value)")
                }
            }
        }
        
    }

En este código básicamente lo que estamos haciendo es lo siguiente:

  • Creamos un ScrollView para que el contenido que añada como hijos de esta vista puedan tener un scroll si el contenido ocupa más espacio que el que nos proporciona la pantalla del dispositivo.
  • Dentro del ScrollView creamos un VStack para que posicionar los elementos internos en forma vertical, uno tras otro.
  • Y por último creo un listado de números con un ForEach que voy a pintar en pantalla mediante una View tipo Text

Esto nos da un listado tal como este:

Hasta aquí todo bien, ¿verdad? 

Bueno, lo cierto es que sí y no. ¿Porqué? Estamos consiguiendo representar en pantalla lo que deseamos, pero si nos fijamos en la cantidad de memoria que estamos utilizando veremos que esta se eleva sobremanera cuando lanzamos la app.

La explicación de esto es sencilla, el código que hemos creado al entrar en el ForEach, ha creado los mil elementos del bucle y los ha cargado en memoria aunque no todos los elementos se estén visualizando en pantalla.

Si añadimos un print() dentro del ForEach veremos que al cargar la app, el bucle es ejecutado 1000 veces y nos pinta por consola todos los elementos que forman el bucle.

Lazy Stack en SwiftUI

Para evitar esta sobrecarga de memoria, SwiftUI nos da unos elementos que son capaces por sí mismos de gestionar la memoria cargando solo aquellos elementos que realmente son necesarios. En una lista por ejemplo, solo se cargarán aquellos elementos que se muestran por pantalla en un momento determinado y cuando ya no esté en pantalla, los sacará de la memoria.

Estos elementos son LazyVStack y LazyHStack. Gracias a estos componentes “perezosos” podemos crear iteraciones o bucles de cientos, miles de elementos que solo se cargarán en memoria únicamente cuando realmente sea necesario, y lo mejor, de manera automática.

Cambiemos el código anterior a este otro:

var body: some View {
        
        ScrollView{
            LazyVStack{
                ForEach(1...1000, id: \.self) { value  in
debug(value: value)
                    Text("Row \(value)")
                }
            }
        }
        
    }

Y ahora al ejecutar la aplicación y abrir la consola veremos como únicamente nos ha pintado por consola aquellos números que se muestran por pantalla. Y si nos vamos al apartado e memoria del Xcode veremos como la cantidad de memoria consumida es bastante menor que en el caso anterior.

Además si hacemos scroll hasta llegar al último elemento de la lista y revisamos de nuevo la cantidad de memoria consumida veremos que en ningún momento se llega al nivel del primer caso, ya que tanto LazyVStack como LazyHStack, se encargan de cargar en memoria y de sacar de esta aquellos componentes que no sean necesarios en un momento concreto.

Así que ya sabéis, cuando necesitéis de crear largas listas de componentes en pantalla, nada mejor que utilizar la versión “perezosa” de las Stacks verticales y horizontales.

El código lo tenéis como siempre en Github.

Comparte si lo consideras interesante
  •  
  •  
  •  
  •  
  •  
  •  
  •  

Deja una respuesta

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

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.