Presentando FlashList: Construyamos juntos una lista performante en React Native

Rate this content
Bookmark

En este masterclass aprenderás por qué creamos FlashList en Shopify y cómo puedes usarlo en tu código hoy. Te mostraremos cómo tomar una lista que no es performante en FlatList y hacerla performante usando FlashList con el mínimo esfuerzo. Utilizaremos herramientas como Flipper, nuestro propio código de benchmarking, y te enseñaremos cómo la API de FlashList puede cubrir casos de uso más complejos y aún así mantener un rendimiento de primera clase.

Aprenderás:

- Presentación rápida sobre qué es FlashList, por qué lo construimos, etc.

- Migración de FlatList a FlashList

- Enseñanza de cómo escribir una lista performante

- Utilización de las herramientas proporcionadas por la biblioteca FlashList (principalmente el hook useBenchmark)

- Uso de los plugins de Flipper (gráfico de llama, nuestro perfilador de listas, perfilador de UIFPS y JSFPS, etc.)

- Optimización del rendimiento de FlashList mediante el uso de props más avanzadas como `getType`

- 5-6 tareas de ejemplo donde descubriremos y solucionaremos problemas juntos

- Preguntas y respuestas con el equipo de Shopify

81 min
19 Oct, 2022

Comments

Sign in or register to post your comment.

Video Summary and Transcription

FlashList es una alternativa a FlatList de React Native que tiene como objetivo un alto rendimiento y facilidad de uso. Proporciona mejoras significativas en el rendimiento en comparación con FlatList, con mayor JSFPS y UIFPS. FlashList se ha implementado con éxito en las aplicaciones Mobile Shop, POS e Inbox de Shopify. El masterclass cubre el proceso de migración a FlashList y técnicas de optimización. FlashList reduce los eventos de desmontaje, soluciona problemas de reciclaje de elementos y mejora el tiempo de carga y el rendimiento de renderizado.

Available in English

1. Introducción a FlashList

Short description:

¡Hola a todos! Mi nombre es Marek, un ingeniero de software en Shopify en Berlín. Voy a presentar FlashList y luego pasaré el turno a Talha. Talha Nikwi, un gerente de desarrollo en Shopify, los guiará a través del taller. David, un gerente de desarrollo de Barcelona, también nos apoyará. Comencemos con FlashList, una alternativa a FlatList de React Native. Hemos tenido problemas con el rendimiento y la capacidad de respuesta de FlatList, por lo que necesitamos una lista más rápida y plana. RecyclistView es una biblioteca de código abierto popular que puede solucionar estos problemas, pero tiene algunas limitaciones como una API complicada y dificultades con alturas dinámicas.

Haré una presentación como introducción a FlashList y luego se lo pasaré a Talha para que dirija el resto del taller. Así que si también quieren presentarse.

Sí, claro. Gracias, Marek. Hola a todos, mi nombre es Talha Nikwi. Soy un gerente de desarrollo aquí en Shopify. Lidero un equipo llamado Retail Dev Accelerate, que se encarga de mucho trabajo relacionado con la infraestructura de nuestra aplicación POS. Tuve la oportunidad de colaborar con Marek y David en el proyecto FlashList. Y los guiaré a través del taller después de que Marek termine hoy. Gracias. Y luego David estará aquí para apoyarnos también, así que si quieres hacer una breve presentación también.

Sí, gracias, Marek. Soy David. Soy de Barcelona, España. Veo que también hay gente de España en la audiencia. Es bueno verlos. Soy un gerente de desarrollo aquí en Shopify desde hace un año y formé parte del equipo de FlashList. Estoy orgulloso de mostrarles esto hoy porque fue un proyecto en el que fue muy agradable trabajar y ver el impacto que está teniendo en la comunidad. Así que estoy contento de estar aquí hoy.

Perfecto. Sin más preámbulos, compartiré mi pantalla para hacer la presentación y sí, comencemos. Genial. Supongo que todos pueden ver mi pantalla ahora para decirme. Como mencioné, mi nombre es Marc Fort y hoy les daré una breve introducción al tema de este taller, que es FlashList. Así que comencemos con un tweet aquí. ¿Y si React Native termina limitándonos? ¿Dónde estamos renderizando? Una lista de tarjetas con marcas de verificación. Ahora, por supuesto, esto es un poco exagerado, pero te da una idea de cómo se perciben las listas en React Native tanto dentro de la comunidad de React Native como fuera de ella. Además, hemos tenido nuestros problemas con FlatList, el componente predeterminado de React Native. Esta es nuestra aplicación de tienda ejecutándose en un dispositivo Android de gama baja Como pueden ver, no es nada receptiva y tiene muchas celdas en blanco que a veces ocupan toda la pantalla. En general, definitivamente no es la experiencia del usuario que queremos para nuestros usuarios. Así que necesitamos una lista más rápida. Y necesitamos una lista plana. Pero primero, consideremos alternativas como RecyclistView. RecyclistView es una biblioteca de código abierto popular que intenta solucionar el rendimiento de las listas en React Native. Y las ventajas son que realmente es rápido si se implementa correctamente. Y la API es altamente personalizable, por lo que se puede lograr casi cualquier cosa con ella. Y también está bastante bien probado. Ha sido utilizado durante varios años en empresas más grandes. Y ha funcionado bien. Pero también tiene algunas limitaciones. Principalmente, la API es realmente complicada, lo que lleva a una experiencia de desarrollo menos deseable. También es bastante difícil lograr celdas de rendimiento con alturas dinámicas. Y además, debido a que Recycler's View es una implementación solo de JS, hay espacios de diseño en la primera renderización que no deberían estar ahí.

2. Implementación y rendimiento de FlashList

Short description:

Construimos nuestra propia versión llamada FlashList para abordar las limitaciones de FlatList. FlashList tiene como objetivo lograr altas tasas de fotogramas, mostrar un número mínimo de elementos vacíos y ser fácil de usar. Utiliza una API similar a FlatList pero introduce props para un mejor rendimiento. FlashList utiliza un Recycle Pool para gestionar eficientemente el renderizado de elementos, ahorrando recursos. También solucionamos el problema de la primera renderización con Auto Layout View. FlashList proporciona una altura de celda dinámica de alto rendimiento y utiliza el motor Recycle. Discutiremos las métricas durante la masterclass, pero las pruebas preliminares muestran mejoras significativas en comparación con FlatList.

Estas limitaciones significaron para nosotros que realmente necesitábamos construir nuestra propia versión en Shopify y la llamamos FlashList. Los objetivos del proyecto han sido lograr una alta tasa de fotogramas tanto para la interfaz de usuario como para JSFPS. Queríamos minimizar tanto como fuera posible la visualización de elementos vacíos y hacer que la biblioteca fuera realmente fácil de usar y lograr el máximo rendimiento posible para una experiencia de desarrollo fluida.

Esta es la API de FlashList que hemos creado y como pueden notar, principalmente hemos cambiado el nombre del componente de FlatList a FlashList y tratamos de mantener la mayoría de las props iguales. Ahora hay algunas props en FlashList que no existen en FlatList para lograr un mejor rendimiento, y aprenderán sobre algunas de ellas más adelante en la masterclass. Las alturas dinámicas no suponen un problema y, como mencioné, eso es incluso con una API similar a FlatList. Así que permítanme responder una pregunta ahora, ¿cómo es que FlashList es tan rápido? Y comenzaré explicando cómo funciona FlatList primero. En FlatList, tenemos algunos elementos en el área visible aquí, índices del cuatro al seis, luego tenemos algunos elementos precargados que están al final de la lista. Y luego tenemos algunos elementos que aún se cargan en la memoria, del dos al tres. Ahora, la cantidad de elementos en memoria en el caso de FlatList es bastante alta. Pero a medida que se desplaza lo suficiente, FlatList necesitará liberar algo de espacio en la memoria. Y ahí es donde entra en juego VirtualizedList, el componente que FlatList utiliza internamente. Y lo que hará es que a medida que te desplazas hacia abajo, vaciará los elementos, por lo que reemplaza el contenido con solo una vista vacía y mantiene las dimensiones de la celda, por lo que el diseño de la lista no cambia. Esto también significa que a medida que te desplazas hacia arriba y llegas a estos elementos vaciados, siempre tendrás que renderizarlos desde cero. Y también, a medida que te desplazas hacia abajo y necesitas cargar más elementos, siempre tendrás que renderizar estos elementos desde cero, lo que consume muchos recursos. Como visualización, aquí puedes ver las celdas con sus IDs de instancia. Y a medida que nos desplazamos hacia abajo, obtenemos más y más IDs, lo que significa que podemos obtener más y más instancias. Y nuevamente, todo debe ser renderizado desde cero. En resumen, Flando utiliza esta lista virtualizada internamente. Y a medida que te desplazas, reemplaza las celdas con contenido vacío. Y lo importante de notar es que las celdas siempre se renderizan desde cero, a menos que estén en memoria, lo que nuevamente consume muchos recursos. Por otro lado, FlashList utiliza un enfoque diferente. Nuevamente, tenemos algunos elementos en el área visible. Tenemos algunos elementos precargados, pero la cantidad de esos elementos es bastante baja. Y lo más importante, tenemos un concepto llamado Recycling Pool. A medida que nos desplazamos por la lista, los elementos que ya no son visibles en la pantalla se colocan en el Recycling Pool. Y luego, cuando necesitamos cargar más elementos, FlashList buscará en el Recycling Pool y, si hay elementos que actualmente no se están utilizando, los moverá de vuelta a la lista y simplemente los volverá a renderizar con los nuevos datos. Esto significa que, por ejemplo, si solo cambia un texto en la celda, solo tendrá que volver a renderizar esa parte y no tendrá que crear nada desde cero. Y eso ahorra muchos recursos. También necesitábamos solucionar el problema de la primera renderización del diseño. Así es como se veía el problema de la primera renderización con Recycle List View, y pueden ver que los elementos se superponen entre sí. Ahora, esto solo ocurre durante un par de fotogramas, por lo que esta grabación se ralentiza para que sea más evidente. Para profundizar en el problema, en el lado izquierdo, tienen cómo Recycle List View espera que se vea el diseño. Espera que cada elemento sea igual, también dependiendo del tamaño estimado del elemento, que es un problema del que también aprenderán más adelante en la masterclass. Pero el diseño real, lo que realmente se muestra en la pantalla, es diferente. Aquí tenemos el elemento número cero que tiene, por ejemplo, 100 píxeles de altura, pero luego el elemento número uno tiene, por ejemplo, 200 píxeles, pero Recycle List View sigue contando con que solo tenga 100. Y luego el elemento número dos se superpone al elemento número uno, lo que resulta en que los elementos se sobrescriban entre sí. Así que implementamos una vista nativa llamada Auto Layout View que recorre toda la lista. Y cada vez que ve elementos que se superponen entre sí o cuando hay espacios entre elementos, automáticamente soluciona esos problemas de interfaz de usuario y coloca todo borde a borde como debería ser. Con FlashList, si observamos la grabación, podemos ver que... En resumen, la implementación de FlashList tiene una API muy similar a FlatList. Hemos implementado una vista nativa para solucionar el problema de la primera renderización. Hemos logrado una altura de celda dinámica de alto rendimiento con una API simple similar a FlatList y hemos utilizado Recycle como el motor interno que hemos construido sobre él para lograr la API.

3. Rendimiento de FlashList y Configuración de la Masterclass

Short description:

FlashList proporciona mejoras significativas en el rendimiento en comparación con FlatList. Logra una mayor JSFPS y UIFPS, lo que resulta en una interfaz de usuario más receptiva. El complemento desarrollado para este proyecto muestra que FlashList tiene significativamente menos espacios en blanco en comparación con FlatList. FlashList está listo para producción y se ha implementado con éxito en las aplicaciones Mobile Shop, POS e Inbox de Shopify. La emoción en la comunidad está creciendo y el proyecto se puede encontrar en GitHub. Ahora, Telha se hará cargo y te guiará a través de la parte de codificación de la masterclass.

Y también te brinda un mejor rendimiento de manera predeterminada. Echaremos un vistazo rápido a algunas de las métricas, pero también obtendrás las métricas de primera mano durante esta masterclass. He estado usando un dispositivo Motorola Moto G10, que es bastante básico, así que tenlo en cuenta al ver los números.

Primero, veamos la interfaz de usuario de FlatList en JSFPS utilizando un ejemplo de Twitter. Muy similar a lo que veremos en la masterclass. Y como puedes ver, el JSFPS cae varias veces a cero y el UIFPS cae por debajo de 10 también. Entonces, lo que obtenemos al final es un JSFPS promedio de 11.8, un promedio de UI de 44 y el bloqueo del hilo JS es de casi dos segundos, lo que significa que durante casi dos segundos el usuario no ha podido interactuar con la pantalla porque eso no es posible cuando el JS está bloqueado.

Si observamos la interfaz de usuario de FlatList en JSFPS con el mismo ejemplo simplemente cambiando el nombre, podemos ver que el JSFPS nunca cae tan bajo, nunca cae ni siquiera cerca de cero, y el UIFPS se mantiene alrededor de 64 la mayor parte del tiempo. Entonces obtenemos un JSFPS promedio de 49 y un UIFPS promedio de 58, lo que es aproximadamente una mejora de cuatro veces solo cambiando el nombre.

También hemos estado observando los espacios en blanco utilizando un complemento de Flipper que hemos construido específicamente para este proyecto. Y como puedes ver con FlatList, obtenemos celdas en blanco enormes que abarcan toda la pantalla, que son las partes grandes reales en la parte superior, y el promedio es de alrededor de 280 píxeles. Con FlashList, obtenemos una historia diferente. Obtenemos algunas celdas en blanco, pero son bastante limitadas y solo aparecen durante un período de tiempo limitado, por lo que el promedio al final es de alrededor de 45, aproximadamente, lo que es siete veces mejor que con FlatList.

Entonces, ¿FlashList está listo para producción? Permíteme volver al ejemplo inicial de la aplicación Shop. A la izquierda, tienes FlatList, que durante varios segundos no fue receptiva en absoluto, y tenía esas enormes pantallas en blanco que llenaban toda la pantalla. Y a la derecha, tenemos algunas celdas en blanco pequeñas, pero solo durante un período de tiempo limitado, y lo más importante, la aplicación es extremadamente ágil, incluso en un dispositivo Android de gama baja como el Moto G10. También lo estamos utilizando en todas nuestras aplicaciones en Mobile Shop, POS e Inbox de Shopify. También hemos visto mucha emoción en la comunidad, y la lista también se está utilizando mucho en producción. Puedes consultar el proyecto en GitHub, pero también lo harás durante esta masterclass. Y eso es todo por mi parte. Ahora le cedo el turno a Telha, quien se adentrará más en la parte de codificación de la masterclass. Gracias.

Gracias, Merik, por la increíble introducción a FlashList. A partir de aquí, me haré cargo. Permíteme comenzar a compartir mi pantalla. Muy bien. Segundo. Bien. Ok. Antes de comenzar, permíteme presentar rápidamente a todos... Bien, incluso antes de comenzar, ¿puedo obtener algunos pulgares arriba en el chat si todos pueden escucharme bien? Y si estás aquí, solo avísame. Genial. Veo algunas respuestas. Muy bien. Muy bien. Ok. Estoy compartiendo un documento en el chat ahora mismo. Asegúrate de usar este enlace y abrir este documento. Esto es lo que verás. Está aquí mismo en mi pantalla. Entonces, estos son básicamente todos los pasos de configuración que tenemos para ti. Voy a guiarlos a través de cada uno de ellos. Solo quiero darte una visión general rápida de lo que puedes hacer en caso de que encuentres problemas. En primer lugar, hay un enlace para preguntas. Asegúrate de usar este enlace para hacernos preguntas y no el chat. Vamos a intentar responder la mayoría de ellas al final de esta masterclass. Hay un enlace a una hoja de seguimiento de rendimiento, del cual hablaré muy pronto. Tienes un enlace a las diapositivas que voy a presentar. Lo más importante, hay una sección llamada `saltar adelante`. En cualquier momento, digamos, si no has podido completar una tarea en particular, puedes saltar a cualquier tarea que desees. Digamos, si saltas a la tarea cuatro, las tareas uno, dos y tres ya estarán completadas en ese snack. Así que no te preocupes si no puedes seguir el ritmo, puedes saltar adelante y hacerlo a tu propio ritmo más tarde.

4. Introducción a la Masterclass y Referencia de Rendimiento

Short description:

Comencemos con la masterclass. Asegúrate de tener Expo Go instalado y abre el enlace proporcionado. Conecta tu teléfono escaneando el código QR. Abre la hoja de seguimiento de rendimiento y agrega tu nombre y dispositivo. El ejemplo es una lista de feeds de Twitter con tweets relacionados. Al hacer clic en un elemento horizontal, se cambia el tweet principal. Ahora, pasemos a la primera tarea. Haz clic en el botón Ejecutar Referencia de Rendimiento y espera el resultado promedio de FPS.

De acuerdo. Entonces, sin más preámbulos, permíteme comenzar con la masterclass, ¿de acuerdo? Comenzaré la presentación.

De acuerdo. Asegúrate de tener Expo Go instalado en tu teléfono. Y asegúrate de abrir el enlace mencionado en el documento aquí, abre el siguiente enlace, puedes abrirlo y verás algo como esto. También voy a escanear este código QR y asegurarme de que mi teléfono esté conectado. Asegúrate de escanear tu propio código QR y no el mío. Aquí vamos. Puedes ver mi dispositivo a la derecha, es el Moto G Stylus. Bien. Así que tengo mi dispositivo conectado en este momento. Puedes ver que este dispositivo aparece en Snap. Puedo hacer clic en el botón de recargar la aplicación en cualquier momento. Y a la izquierda, puedes hacer clic en los mensajes de no errores y una advertencia y registros para ver los registros que aparecerán. Esa fue una breve introducción sobre cómo funcionará Snap.

De acuerdo. Como segundo paso, vuelve al documento y abre la hoja de seguimiento de rendimiento. Se verá algo como esto. Entonces, lo que quiero que hagas después de haber lanzado el ejemplo y poder verlo en tu aplicación ExpoGo, simplemente marca esta casilla y agrega tu nombre y dispositivo a la izquierda. Así es como podemos hacer un seguimiento del progreso de todos. Joshua, asegúrate de que tu aplicación ExpoGo esté actualizada. De acuerdo. Continúa y agrega tus nombres. Bien, el primer dispositivo Android en la lista. Me alegra ver eso. También está el iPhone 14 Pro Max. ¿Hay alguien que esté teniendo algún problema? Adelante, adelante. Sí, no te preocupes por el resto de las columnas. Te guiaré en lo que vamos a hacer exactamente, y lo haremos juntos. Simplemente agrega tus nombres, tu dispositivo y si has cargado el ejemplo en tu aplicación Xpogo. De acuerdo, exploraremos rápidamente de qué se trata el ejemplo y luego comenzaremos con la primera tarea. Este ejemplo es una lista de feeds de Twitter, y algunos de estos tweets tienen tweets relacionados junto con ellos. Entonces, si te fijas, cualquier cosa que tenga más de dos retweets tiene un tweet relacionado. Es una combinación de listas verticales y listas horizontales. Si haces clic en cualquiera de los elementos horizontales, cambiará el tweet principal. Y el elemento se seleccionará. Eso es todo lo que hace este ejemplo. Siéntete libre de jugar con él.

Continuando, pasaré a la siguiente tarea y comenzaremos a hacer cosas ahora. De acuerdo, ¿cuál es lo primero? Lo que queremos hacer es, si te fijas, hay un botón Ejecutar Referencia de Rendimiento en la parte superior. Quiero que todos hagan clic en él y esperen a que se ejecute y finalice la referencia de rendimiento. Al finalizar, te dará un número promedio de FPS. Lo haré junto contigo. Hagámoslo juntos. De acuerdo. Bien, el mío se está ejecutando. De acuerdo, obtuve un resultado. Mi FPS promedio fue de 1.7. Recuerda, mi dispositivo es bastante básico. Es un Moto G Stylus con un Snapdragon 665.

5. Finalización de la Referencia de Rendimiento y Siguiente Paso

Short description:

Después de completar la referencia de rendimiento, ingresa el número promedio en la columna de referencia. Asegúrate de recargar la aplicación y elegir el enlace correcto si es necesario. El número de rendimiento depende del dispositivo utilizado. Las listas anidadas verticales y horizontales pueden ser complejas. Asegúrate de utilizar el ejemplo correcto. Pasemos al siguiente paso.

Entonces, después de que hayas terminado, lo que quiero que todos hagan es ir y poner este número promedio en la columna de referencia. Solo tienes que hacer clic en el botón de ejecutar referencia de rendimiento y esperar. Muy bien, muy bien. Muchas personas han podido hacerlo. Recuerda, debes poner el número promedio y no el FPS máximo. Sí, Josh, tu número es bastante alto. Si crees que no has obtenido el número correcto, asegúrate de recargar la aplicación y asegúrate de haber elegido el enlace correcto y simplemente ejecuta la referencia de rendimiento nuevamente, y luego puedes actualizarlo más tarde. Sí, este número depende del dispositivo performance, y estoy utilizando un dispositivo muy básico, Moto G Stylus, Snapdragon 665. Flat list, todos los elementos están memorizados. Todo está como debería ser. Es solo que cuando tienes una lista vertical y una lista horizontal anidadas juntas, es algo bastante complejo. ¡Ah, eso es! Abriste directamente el ejemplo final. Muy bien, Joshua, asegúrate de corregirlo. Así que seguiremos adelante en aras del tiempo porque realmente quiero responder preguntas al final.

6. Descripción general del ejemplo y comienzo de la migración

Short description:

Veamos el ejemplo y comencemos la migración a FlashList. Cambia el nombre a FlashList e impórtalo. Recarga la aplicación. Se ha completado el primer paso de la migración.

De acuerdo, ¿cuál es el siguiente paso? Lo que queremos hacer ahora es ver el ejemplo, ¿de acuerdo? Si abres la carpeta SRC dentro de Twitter, encontrarás tres archivos: TweetSell, TweetContent, y Twitter. Twitter es donde se define nuestra lista plana. Así que lo que quiero que todos hagan es comenzar la migración a FlashList. Voy a hacer las primeras cosas contigo, así que sígueme, pero el resto de las tareas, puede que me detenga un minuto o dos y te deje hacerlo. Lo que necesitamos hacer es simplemente cambiar el nombre a FlashList y necesito importarlo. Eso es todo. Cambia el nombre a FlashList y voy a recargar la aplicación. De acuerdo. Y eso es todo. Hemos completado el primer paso para migrar a FlashList.

7. Observando el Tiempo de Carga y Optimizando el Rendimiento

Short description:

Observamos el tiempo de carga de la lista y descubrimos que tardaba más de un segundo en renderizarse. FlashList sugirió establecer el tamaño estimado del elemento en 279 píxeles, lo que mejoró significativamente el tiempo de carga a 485 milisegundos, reduciéndolo en más del 50%. Es crucial especificar el tamaño estimado del elemento para optimizar el rendimiento. Luego procedimos a repetir el proceso y registramos un JSFES de 2.9 en la tarea 1.

¿Cuál es lo siguiente que queremos hacer? Lo que queremos hacer ahora es observar el tiempo de carga de esta lista. ¿Qué es el tiempo de carga? El tiempo de carga es el tiempo que tarda en mostrarse los elementos en la pantalla y FlashList tiene una API genial que te permite hacer eso. Así que voy a hacer eso. Por supuesto, estoy copiando y pegando algo de código, pero siéntete libre de escribirlo.

Así es como se hace. Agregas un listener de carga. Te proporciona un objeto del cual puedes seleccionar el tiempo transcurrido en milisegundos y puedes registrarlo. Así que voy a recargar la aplicación nuevamente y verás que aparecerá el tiempo de carga. Muy bien. Entonces, mi tiempo de carga para esta lista es de 1319. Muy largo. Tarda más de un segundo en renderizarse. Si te fijas, FlashList nos está dando una advertencia aquí. Dice que el tamaño estimado del elemento no está definido. Y según la configuración actual, puedo establecerlo en 279 para optimizar el rendimiento.

¿Qué significa esto? Antes de renderizar, FlashList generalmente tiene que adivinar cuántos elementos debe comenzar. Y en muchos casos, esa estimación puede ser incorrecta. En este caso particular, podría pensar que cada elemento tiene 100 píxeles. Pero después de renderizar, como desarrollador, ahora sé que mis elementos tienen 279 píxeles y FlashList me está dando esa sugerencia. Y puedo proporcionar esta información a FlashList de antemano y puede usarla para optimizar algunas cosas. Así que vamos a hacer eso. Lo que haremos es establecer el tamaño estimado del elemento en 279. Una vez que haya hecho eso, volveré a cargar la aplicación. Esperemos a que aparezca el tiempo de carga. Muy bien. Ahora mi tiempo de carga es de 485 milisegundos. ¿Qué sucedió aquí? FlashList pudo hacer una suposición mucho mejor sobre cuántos elementos necesita al principio. Eso llevó a un menor número de elementos montados. Y, si te fijas, ya hemos reducido los tiempos de carga en más del 50% solo especificando ese tamaño estimado del elemento. Es extremadamente importante que se especifique. Hemos visto el tamaño estimado del elemento y su impacto. Ahora, dame un pulgar hacia arriba rápido si has podido hacer esto. Pulgar hacia arriba. Listo. ¿Algo en el chat? Genial. Veo que aparecen algunas cosas. Eso es genial. Muy bien. Entonces, repitamos lo que hicimos la primera vez. Vamos a hacer clic en Ejecutar Benchmark Juntos en el código actualizado y registraremos los números en la tarea 1. Déjame hacerlo. Muy bien. Está corriendo para mí. Muy bien. Todo en blanco. De acuerdo. El JSFES ahora es solo 2.9. Aún bastante malo. Voy a guardarlo debajo de mi fila. 2.9.

8. Observando Eventos de Montaje y Desmontaje

Short description:

Pasemos a la tarea dos. Queremos observar el número de eventos de montaje y desmontaje en la celda de tweet y el contenido del tweet. Usaremos un fragmento de código y recargaremos la aplicación para observar los eventos. Una vez que tengamos los datos, ejecutaremos el benchmark nuevamente. Recuerda comentar el console.log para evitar impacto en el rendimiento.

De acuerdo. Me alegra ver que muchos de ustedes pudieron hacerlo. Asegúrate de elegir el número promedio y no el máximo o el mínimo.

De acuerdo. Muy bien, pasemos a la tarea dos. Correcto, lo que queremos hacer es, como Merrick describió, el objetivo de FlashList es reducir la cantidad de elementos que se crean y destruyen. ¿Cómo podemos observar eso? Podemos usar el siguiente fragmento de código dentro de nuestros elementos de celda de tweet y contenido de tweet.

Y, muy bien, Mia, simplemente puedes hacer clic en el enlace aquí y la tarea uno ya estará hecha para ti. Y puedes comenzar directamente con la tarea dos si no pudiste terminarla. Pero si necesitas unos minutos extras, adelante, tómalos. De acuerdo. Muy bien. Entonces, sigamos adelante y hagamos esto. Primero, voy a ir a la celda de tweet y. Voy a usar useEffect. Y useEffect. Y aquí voy a devolver una función. Que va a. Hacer console.log. console.log. Celda de tweet. Estoy montado. Y queremos que esto se ejecute solo cuando el componente se monte, así que pasamos un arreglo de dependencias vacío. Un código muy simple.

Y lo mismo lo voy a copiar. Y pegar dentro del contenido de tweet. Eso está en la línea 72. Y voy a cambiar mi console a Contenido de tweet. Y voy a importar useEffect. Tómate tu tiempo. No hay prisa. Ya terminé. Voy a recargar la aplicación ahora. Dame un pulgar hacia arriba si has hecho esto. Increíble. Genial, genial, genial. De acuerdo, de acuerdo, observemos. Voy a borrar los registros existentes. Veamos. Voy a desplazarme manualmente, y bien. Ves que nuestra celda de tweet se desmonta todo el tiempo. El contenido del tweet también se desmonta. Muchos eventos de desmontaje y montaje, y esto es algo que realmente queremos evitar. De acuerdo, la idea de esta tarea en particular era simplemente observar cuántos montajes y desmontajes tenemos, y luego ejecutar el benchmark una vez más. Así que hagámoslo.

9. Console Log, Key Prop, and Flashlist

Short description:

Comenta el console.log, recarga la aplicación, ejecuta el benchmark. Los resultados pueden variar en dispositivos Android de gama baja. Tarea 3: Eliminar las claves asignadas en Flashlist. Las claves se agregan a menudo en Flatlist, pero en Flashlist pueden marcar una gran diferencia. Elimina una clave del elemento de renderización principal en Twitter. Busca la otra clave en el contenido del tweet. Elimínala. Recarga la aplicación.

Asegúrate de comentar el console.log, porque afecta el rendimiento. Pero vamos a descomentarlo en la próxima tarea. Así que voy a comentar el console.log, recargar la aplicación, esperar a que se cargue. Y volvamos a ejecutar el benchmark. De acuerdo, para mí el resultado es de 8.9 FPS. ¿Correcto? Creo que no hizo mucho por cambiar el rendimiento en absoluto. Dado que este es un dispositivo de gama baja, a veces los resultados pueden ser un poco inestables, y creo que eso es lo que sucedió porque ciertamente no hice ningún cambio para mejorar nada. De acuerdo. Así que vamos a capturar esos resultados. Muchos de ustedes ya tienen 41, 47, 44, 56. Sí. Quiero decir, iPhone 13 y iPhone 14 Pro, tienen un rendimiento de un solo núcleo realmente sólido. Es por eso que pueden resolver algunos de estos problemas de rendimiento a la fuerza bruta. Pero en dispositivos Android de gama baja, e incluso en dispositivos Android de gama media, se ven muchos más problemas. Creo que eso es lo que reflejará el resultado. Muy bien. Pasaré al siguiente una vez que estemos por encima del 50 por ciento. Vamos. Sí, a veces Snag no se recarga. Si tienes sospechas, simplemente haz clic en recargar desde la consola web o agita el dispositivo y usa el botón de recarga. Muy bien. Sigamos adelante. ¿Cuál es la tarea 3? Quería tocar rápidamente la función de la clave y react. Básicamente, cuando la clave mapea tu instancia de JS a una instancia de UI real en el DOM, y cuando cambias una clave en React, va a recrear tanto el nodo de UI como el nodo de JS. Esto es específicamente lo que queremos evitar en Flashlist. La siguiente tarea consiste en averiguar dónde se han asignado explícitamente estas claves, y las vamos a eliminar para ver su impacto en las operaciones de montaje y desmontaje. Hemos observado que en muchos casos, cuando usas Flatlist, tiendes a agregar estas claves, porque no se ve realmente afectado por ello. De todos modos, se destruye y se recrea, por lo que tenerlo o no tenerlo no marca mucha diferencia. Pero como notarás, en el caso de Flashlist, puede marcar una gran, gran diferencia. Voy a eliminar una, y luego te haré buscar la otra. Muy bien, si vas a Twitter, verás que el elemento de renderización principal tiene una clave explícita definida. Lo que queremos hacer es eliminarla. Eso es todo. Y también queremos volver a tweet cell y descomentar nuestro console.log para que podamos observar nuevamente los eventos de desmontaje. Esa fue la primera clave. Intenta encontrar la otra clave si está definida en algún lugar. Y avísame dónde está en el chat. Puede estar en cualquiera de estos componentes. Esperaré un minuto y luego continuaremos. De acuerdo, parece que la gente ha encontrado dónde está la, dónde está la clave. Sí, está dentro de tweet content. y está en la línea número 78. Si ves esto, esto, esta clave ni siquiera es parte de ninguna declaración de mapeo. Realmente no es necesario a menos que alguien quiera destruir y recrear este elemento explícitamente. Así que podemos eliminarlo. Recarguemos la aplicación. De acuerdo, dejemos que se recargue. A veces tarda un poco incluso después de que aparezca. Ahora realmente se recargó. De acuerdo, déjame desplazarme.

10. Fixing Unmounting Issue and Running Benchmark

Short description:

El contenido del tweet sigue desmontándose, pero la celda del tweet ya no se desmonta. Esto se debe a que eliminamos la clave prop definida en la celda del tweet. Pronto resolveremos el problema de desmontaje del contenido del tweet. Vamos a eliminar el useEffect para rastrear los desmontajes y comentar el desmontaje del contenido del tweet. Luego, ejecutaremos el benchmark nuevamente para verificar si hay alguna mejora.

Correcto. Si te fijas, el contenido del tweet sigue desmontándose, pero la celda del tweet ya no se desmonta en absoluto. No veo ningún registro allí. Y la razón es porque eliminamos la clave prop que estaba definida en la celda del tweet. Entonces, el único problema que tenemos ahora es el desmontaje del contenido del tweet, y resolveremos eso muy pronto. Dado que la celda del tweet ya no se desmonta, voy a eliminar este useEffect para rastrear los desmontajes. Y, como hicimos la última vez, comentaré el desmontaje del contenido del tweet, porque interferirá con nuestros benchmarks. Así que coméntalo, recarga, vamos a hacerlo. Y luego ejecutaremos el benchmark nuevamente para ver si hay alguna mejora.

11. Resultados de referencia y Tarea Cuatro

Short description:

La lista se cargó en 491 milisegundos. Alguna mejora, pero aún no es excelente. Pasemos a la tarea cuatro.

De acuerdo, déjalo recargar. Bien, mi lista se cargó en 491 milisegundos, dale un pulgar hacia arriba si estás listo para ejecutar la referencia. De acuerdo, genial, muy bien. Hagámoslo. Oh, todavía se queda en blanco. Si te fijas, mi Moto G stylus se queda completamente en blanco en la mayoría de las ejecuciones. Muy bien, 11.6. En mi caso, hay una pequeña mejora, pero nada importante para celebrar realmente. Todavía es bastante malo, ¿verdad? Continúa con tus referencias y luego pasaremos a la tarea cuatro. Aquí es donde creo que las cosas empezarán a ponerse interesantes. Sí.

12. Solución al problema de reciclaje de elementos

Short description:

Los elementos se repiten porque no se actualizan cuando se reciclan. Esto no es un problema en FlatList, pero en FlashList, el tweet actual permanece igual cuando se actualiza el elemento. Podemos solucionar esto utilizando el hook useEffect. Si currentTweet no es igual a tweet, podemos llamar a setCurrentTweet con un nuevo tweet. Después de recargar, el problema debería estar solucionado. Volvamos a ejecutar la prueba de referencia y analicemos los resultados.

De acuerdo, hemos superado el 50%. ¿Notas algún problema con la lista en este momento? Desde que eliminamos esa clave. Si ya ves el problema, puedes comentarlo. De acuerdo, déjame mostrarte. Mira los elementos superiores. El primer tweet es de Chris, el segundo es de Lorenzo. Sí, alguien lo ha entendido. Los elementos se repiten. Si vuelvo al principio de nuevo, los tweets cambian. ¿Por qué está sucediendo esto? Esto sucede porque los elementos se están reciclando y cuando se reciclan, no se están actualizando. Sé que esto también podría ser debido a que mi performance mejoró. Porque no está sucediendo nada, los elementos ya se están moviendo. Así que te mostraré rápidamente qué está sucediendo y por qué es un problema y cómo podemos solucionarlo y luego lo solucionaremos juntos. Si te fijas, a cada celda, te lo dije, que cuando haces clic en uno de los elementos horizontales, cambia el tweet de nivel superior. Y este tweet actual se mantiene utilizando un estado, cada vez que ocurre ese clic, se actualiza el estado. Pero cuando el elemento se está reciclando realmente, el estado no cambia, por lo que el tweet actual se conserva y ahí está todo el problema. Esto no es un problema en FlatList porque cuando recrea el elemento, tu tweet actual siempre es igual al tweet entrante. Pero aquí, cuando este elemento se actualiza, el tweet actual sigue siendo el mismo. ¿Alguna idea, alguien quiere comentar rápidamente en el chat cómo podemos solucionarlo? Correcto. Perfecto. De acuerdo, es nuestro hook favorito, useEffect. Permíteme mostrarte cómo puede funcionar. Este es el fragmento de código que vamos a utilizar. Entonces, lo que tenemos que hacer es, hagámoslo juntos. useEffect. Lo que queremos comprobar es si currentTweet no es igual a tweet, queremos llamar a setCurrentTweet con un nuevo tweet, y queremos ejecutar esto solo si nuestro tweet cambia y no en ninguno de esos clics de elementos horizontales. Entonces, el tweet solo cambiará cuando FlashList reutilice un componente existente, y ahí es donde queremos asegurarnos de que estamos sincronizando el estado. Siéntete libre de copiar este fragmento de código, useEffect si currentTweet no es igual a tweet, setCurrentTweet, y formatea para que se vea claro. Voy a recargar. Muy bien, ha recargado. Entonces, mis primeros dos tweets son de Aaron y de Gargley. Y déjame desplazarme. No estoy seguro de si estoy pronunciando sus nombres correctamente, pero perdóneme. Si vuelvo hacia arriba, verás que todo está bien ahora. No hay elementos que se repitan. ¿Todos han podido solucionar el problema? Dame un pulgar hacia arriba si ahora está solucionado para ti. Muy bien. Genial, me alegra ver que todos pueden seguirlo fácilmente. Estábamos bastante aprensivos, sinceramente, al principio ¿es demasiado difícil? Incluso hicimos una prueba ayer solo para asegurarnos de que no fuera demasiado difícil. De acuerdo, si todos están listos, volvamos a ejecutar la prueba de referencia. Y veamos los resultados. Estamos agregando otro renderizado. Así que podría ralentizarse. Descubrámoslo. Mientras tanto, ¿alguien puede decirme si esta quizás no es la mejor manera de actualizar el elemento y cuál puede ser el problema potencial? De acuerdo, si ves mis números, en realidad han disminuido a 6.6. No veo muchas mejoras. De acuerdo. Oh, todos ya están más allá del 50% con lo que puse en mis números. Eso es genial. Me alegra ver esto. De acuerdo.

13. Migrando la Lista Horizontal a FlashList

Short description:

Vamos a migrar la lista horizontal a FlashList y buscar errores. Después de migrar, FlashList reduce agresivamente las renderizaciones, lo que hace que el elemento no se resalte cuando se hace clic en él. Podemos solucionar esto utilizando la propiedad extra data para pedirle a FlashList que vuelva a renderizar cuando cambie el tweet actual. Después de recargar la aplicación, el problema debería estar solucionado y el tiempo de carga debería reducirse significativamente. Ejecutemos nuevamente el benchmark para verificar los nuevos números de rendimiento.

De acuerdo, sigamos adelante. Tarea número cinco. Si te das cuenta, la lista horizontal también es una lista plana. Así que lo que queremos hacer es migrarla a FlashList y buscar errores. Así que adelante y hazlo. Nuevamente, cuando migres, te dará una sugerencia para el tamaño estimado del elemento. Voy a esperar un minuto para que todos lo hagan antes de hacerlo yo también, ¿de acuerdo? Y luego discutiremos el error y cómo podemos solucionarlo.

De acuerdo, hagámoslo en 40 segundos. No debería llevar mucho tiempo y luego lo haré yo. También intenten encontrar o notar cualquier error si los hay. De acuerdo, también comenzaré a hacerlo. Tengo que ir a la celda de tweets. Cambiaré FlatList por FlashList. Necesito importarlo, importar FlashList de ese FlashList de Shopify. Ahora voy a recargar. Y espero que me dé una sugerencia para el tamaño estimado del elemento porque no quiero adivinarlo ahora mismo. De acuerdo, tengo una sugerencia, es 352. Déjame agregar ese tamaño estimado del elemento 352 y recargar una vez más. ¿Alguien ve algún problema? Algunos elementos pueden repetirse en la lista horizontal porque estamos generando recomendaciones aleatorias para ella, pero la repetición no es el problema.

De acuerdo, te mostraré cuál es el problema. Cuando haces clic en cualquiera de estos elementos, el tweet superior va a cambiar pero el elemento en sí no se va a resaltar. Anteriormente, se mostraba un borde azul claro. Eso ya no está sucediendo, aunque está funcionando. Entonces, ¿por qué sucede eso? La razón de esto es que FlashList es extremadamente agresivo al reducir las renderizaciones. En lugar de optar por no volver a renderizar utilizando useMemo y cosas así, es mejor optar por volver a renderizar. Entonces, si tus datos han cambiado y tu elemento final ha cambiado, solo en ese caso, FlashList hace una renderización completa de los elementos, de lo contrario no lo hará. Y si ves, el color del borde depende de si el tweet actual, como el tweet mostrado, es el tweet actual o no, y si esta condición es verdadera, el borde cambia. Pero en este caso, FlashList no va a volver a renderizar en absoluto porque los datos no han cambiado cuando hacemos clic en el elemento. Entonces, ¿cómo solucionamos esto? Usamos la propiedad extra data, que forma parte tanto de FlatList como de FlashList, y le pedimos a FlashList que también vuelva a renderizar si cambia el tweet actual. De acuerdo, voy a recargar la aplicación nuevamente, y una vez que se actualice, este problema debería estar solucionado. De acuerdo, recarguemos. Muy bien. Si ves, mi tiempo de carga se redujo nuevamente en casi un 50%. Comencé con 1.3 segundos, y ahora son 238 milisegundos. Es una mejora increíble. Pero veamos si nuestro error está solucionado. Muy bien, sí. Puedo ver el borde azul claro nuevamente. Eso es genial. De acuerdo. Muy bien, ahora volvamos a ejecutar el benchmark y veamos nuestros nuevos números de rendimiento al final de la tarea cinco, ¿de acuerdo? Ahora se ve mejor. Mucho mejor. Al menos para mí lo es. Aha, 21.2. Es una mejora bastante grande en realidad. Es muy probable que las personas con iPhones ya estén alcanzando la línea superior de 60 en este punto. De acuerdo. Eso fue todo. Antes de continuar, también voy a hacerlo rápidamente y no tienes que hacer esto, puedes simplemente observarlo conmigo.

14. Solucionando el Problema de Desmontaje y Reduciendo los Desmontajes

Short description:

Descomentaré el console.log y volveré a cargar la aplicación para ver si el contenido del tweet sigue desmontándose. Si lo hace, investigaremos más a fondo. Analizaremos el código para entender por qué siguen ocurriendo los desmontajes. Al verificar la condición en la celda del tweet, podemos determinar si se está ingresando a la lista Flash. Tenemos una lógica fija para decidir si mostrar tweets relacionados basados en el recuento de retweets. Usaremos el fragmento de código getItemType para informar a FlashList sobre el tipo de elementos y reducir la cantidad de desmontajes. Después de recargar y observar, podemos ver que no hay eventos de desmontaje repetidos.

Descomentaré este console.log y volveré a cargar la aplicación nuevamente. Y verás que el contenido del tweet ya no se desmontará porque hemos cambiado a FlashList. Muy bien. En cuanto a los desmontajes, estos son los elementos anteriores. Permíteme deshacerme de los registros. Ahora voy a desplazarme, ¿de acuerdo? Oh Dios, todavía se está desmontando. Eso es extraño. De acuerdo. Bien, ¿qué podría estar sucediendo? De acuerdo, volvamos a cargar una vez más. Tal vez todavía haya algo mal. No. De acuerdo, recárgalo nuevamente. Veamos. Bien, hay algunos desmontajes ocurriendo, lo cual está bien. Descubriremos por qué sucede eso. Muy bien. De acuerdo. Entonces, en sí mismo, tenemos bien. Pasemos a la tarea número seis.

Obtener tipo de elemento. ¿Qué es obtener tipo de elemento? Esta es la pieza final del rompecabezas, si lo pongo de esa manera. Si te fijas, los desmontajes siguen ocurriendo porque podríamos elegir la base incorrecta para reciclar elementos. Por ejemplo, este tweet en particular no tiene tweets relacionados. Y podría ser reciclado y reutilizado para renderizar un tweet que tiene tweets relacionados. Y lo que eso significa es que vamos a ver muchos eventos de montaje como parte de eso. Y viceversa, si uso este tweet, que tiene tweets relacionados, para renderizar algo que no tiene esos tweets relacionados, todos esos tweets relacionados que hemos renderizado antes se desperdician. Veamos el código para entender por qué sucede esto. Dentro de la celda del tweet en la línea número 34, verás una comprobación donde estoy verificando si la longitud de las recomendaciones es mayor que cero, solo entonces ingresamos a la lista Flash. Entonces, si esta condición no coincide con la solicitud, si hay una discrepancia entre los elementos, podemos encontrarnos con ese problema. Pero ya tenemos una lógica fija para decidir si vamos a mostrar tweets relacionados que básicamente es esto. Aquí es donde estamos verificando si tweet.retweetcount es mayor que dos. Generamos algunos tweets relacionados y los mostramos al usuario. ¿Qué pasa si le decimos a FlashList que estamos haciendo algo como esto? Y FlashList tiene una forma en la que puedes hacer eso. Muy bien, ¿cómo funciona esto? Este es el fragmento de código que vamos a usar. Obtener tipo de elemento, puedes ir a tu elemento de Twitter de nivel superior y agregar este código. ¿Cuál es el código? Obtener tipo de elemento, obtendrás un elemento. Y si el recuento de retweets del elemento es mayor que dos, le decimos a FlashList que esto es como un elemento de tipo RT, que es una abreviatura de tweets recomendados o tweets relacionados. Si el recuento de retweets es menor o igual a dos, devolvemos T. De esta manera, FlashList ahora puede determinar internamente qué elementos debe reciclar y qué tipo de elementos debe usar. Y esto va a reducir aún más la cantidad de desmontajes que estamos viendo. Aquí, déjame recargar. Mi console.log ya está descomentado, como puedes ver aquí, observaremos si todavía estamos viendo algún desmontaje. Sí. Muy bien. Todo está cargado, déjame desplazarme. Sí, algunos desmontajes, dos desmontajes. Flash escanea y desmonta algunas cosas basado en varios factores que no necesita. Pero incluso al desplazarnos bastante, ¿verdad? Puedes ver que no estamos obteniendo eventos de desmontaje repetidos en absoluto. Bien, te doy un minuto para hacer esto.

15. Optimizando las Actualizaciones de Estado con Refs

Short description:

Los desmontajes han desaparecido, se puede eliminar UseEffect. Ejecuta la prueba de rendimiento para ver mejoras en los números. Discutiendo una forma alternativa de actualizar estados y evitar renders adicionales. Crea una referencia para rastrear el tweet de origen. Verifica si el tweet de origen es igual al tweet pasado por FlashList. Si no lo es, guarda una copia en la referencia y llama a setCurrent en la misma llamada de renderizado. Este método es más rápido que usar UseEffect.

Y dale un pulgar arriba una vez que tampoco veas ningún desmontaje. ¿Alguien escaneó mi código QR? Vi un iPhone. Vi el registro del iPhone. Genial, creo que algunos de ustedes ya pudieron hacerlo. Pero sí, los desmontajes han desaparecido por completo. Eso es genial, y eso es lo que nos propusimos hacer desde el principio. De hecho, voy a eliminar este UseEffect porque nada se desmonta, así que no lo necesito. Voy a recargar una vez más. Quien se haya conectado a mi snack, su aplicación también se recargará. De acuerdo, veamos. De acuerdo. De acuerdo. Genial. Hagámoslo de nuevo. Ejecutemos la prueba de rendimiento y veamos los nuevos números. Se ve mucho mejor. Estoy emocionado de ver cómo serán los nuevos números. Y recuerda, mi iPhone también está grabando. 32.4. 32.4 para mí. 32.4. 34. Y mira, incluso si no tienes un dispositivo de gama baja en este momento, todo el material está ahí, el snack está ahí, así que en el futuro, carga el snack inicial en un dispositivo de gama baja y luego prueba el final para ver qué mejora puedes esperar. Pero sí, en un iPhone, ya habrías alcanzado el límite en este momento. Porque el renderizado de JS no va a capturar más de 60 FPS por ahora. Muchas personas podrían estar en 60 FPS, sinceramente, en este punto, pero queda una tarea más. No ha terminado. De acuerdo. ¿Qué pasa, si recuerdas, en una de las tareas, agregamos un UseEffect. Y esto es algo en lo que quería profundizar exclusivamente, porque generalmente las personas agregan UseEffects para actualizar sus estados y sincronizarlos con datos externos. Pero hay una forma alternativa en la que puedes evitar el renderizado adicional. Nuestra configuración actual, si vuelvo al código, este UseEffect se llamará después de que hayamos realizado una actualización, y luego verificará esta condición llamada setState, lo que significa que el elemento se renderizará dos veces. Y algunos de estos elementos tienen estas listas horizontales anidadas que son muy costosas de renderizar. Así que definitivamente no queremos hacerlo dos veces. Entonces, veamos si podemos hacerlo solo una vez y cómo hacerlo. De acuerdo. Entonces, el fragmento de código está frente a ti. Déjame hacerlo y puedes seguirlo. Lo que puedo hacer es crear esta referencia source para rastrear cuál es mi tweet de origen, ¿verdad? Que proviene, digamos, de FlashList. Hice una copia de eso. En lugar de UseEffect, ahora voy a hacerlo en el mismo bucle de renderizado, o camino de renderizado. Voy a verificar si mi tweet de origen es igual al tweet que ahora se pasa por FlashList. Si no lo es, guardamos una copia en la referencia y llamamos a setCurrent en la misma llamada de renderizado. Lo que esto hace es, en este caso particular, digamos que hablo del contenido del tweet, entonces el método de renderizado de la celda del tweet, nuestro componente actual se llamará dos veces, pero el renderizado del contenido del tweet se llamará una vez. Así que son como dos renderizados, pero debajo de ese árbol es solo un renderizado. Entonces FlashList también se renderizará solo una vez. Entonces, si lo haces de esta manera, hay, por supuesto, varias formas de hacerlo, y React tiene esto documentado sobre cómo funciona y por qué es mejor que usar UseEffect. Pero para FlashList, recomendamos encarecidamente que si tienes estados, los sincronices usando este método porque es mucho más rápido que usar UseEffect. Nuevamente, las mejoras dependen de tu componente en particular, pero como verás en este caso, marcará la diferencia. Sí, déjame recargar.

16. Observando la Distancia de Dibujo y los Resultados Finales

Short description:

Observemos si el error de elementos repetidos aún existe. Cambia la propiedad de distancia de dibujo en FlashList para mejorar el rendimiento. Recarga la aplicación y ejecuta la prueba final. Los resultados muestran mejoras significativas en JSFPS, especialmente en dispositivos Android. Incluso en iPhones, FlashList consume menos CPU en comparación con FlatList. También se mejora la duración de la batería y la temperatura del dispositivo. Echemos un vistazo rápido a los resultados. La parte de codificación de la masterclass ha finalizado. Hemos visto mejoras de rendimiento notables con FlashList. Hay una cosa más interesante por explorar: JSThread.

Y también vamos a observar si todavía vemos ese error de elementos repetidos o no. De acuerdo, se ha recargado, déjame desplazarme un poco. Déjame volver. Bien, todo se ve bien. Sí. Dale un pulgar arriba si pudiste hacer esto. Increíble, genial. De acuerdo, aún no vamos a ejecutar la prueba final. Hay una cosa más. De acuerdo, distancia de dibujo. Muchos de ustedes estarán familiarizados con la propiedad de tamaño de ventana en FlatList. FlashList también tiene una propiedad, se llama distancia de dibujo en este caso. Puedes cambiar esta propiedad a un valor más pequeño, por defecto, FlashList solo dibuja 150 píxeles por delante mientras que FlatList dibuja 10 veces el tamaño de tu vista previa de antemano. Entonces FlashList dibuja una cantidad minúscula de elementos en comparación con FlatList. Pero en el caso de una lista horizontal, ni siquiera necesitas dibujar 250 píxeles por adelantado. Al menos, ya sabes, en este ejemplo en particular, el elemento es bastante grande, así que probablemente pueda cambiar también la distancia de dibujo. Voy a ponerla en cero. También puedes optar por no hacerlo, incluso sin hacerlo, veremos muchas mejoras, pero hagámoslo porque sabemos que realmente no necesitamos hacerlo. Y en el caso de FlashList, establecerlo en cero no va a causar ningún problema funcional importante. Como en el caso de FlatList, sé que en algunos casos cuando cambias el número inicial para renderizar o el tamaño de la ventana, puedes tener problemas. Los elementos no se cargan, pero en este caso en particular no hay compromiso. ¿De acuerdo? Si has terminado de configurar la distancia de dibujo de la lista interna, recarga la aplicación y vamos a hacer la ejecución final. De acuerdo, solo 200 milisegundos de tiempo de carga. De acuerdo, hagámoslo. Bien, se ve bastante bien. Ya no veo espacios en blanco. De acuerdo, vamos, vamos, vamos. 50.6, 50.6 para mí. De acuerdo, 50.6. Los resultados de Zach son bastante interesantes. Comenzó con 60 FPS. Aún en 60 FPS. Muy bien. Así que eso es la distancia de dibujo. Creo que hemos terminado, hemos terminado, y eso nos lleva al final de la parte de codificación real de la masterclass. Echemos un vistazo rápido a los resultados. En mi caso, si ves, comencé con 1.7 FPS en un dispositivo de gama baja. Zach, está bien. Y mi número final fue 50.6. Así que en realidad aumenté mi JSFPS a 40, es decir, 48.9 FPS más, y eso constituye una mejora de 29 veces en JSFPS, ¿verdad? Y si observo algunos de los iPhones que vimos, mira, algo interesante a tener en cuenta aquí es que incluso en el iPhone, si solo ves una mejora de 1.2X, FlashList en realidad estará consumiendo una cantidad muy pequeña de CPU en comparación con FlatList. Entonces, la fuerza bruta es posible, pero estás consumiendo mucha, mucha energía y batería, tu dispositivo se calentará, cosas así. Así que seguirás viendo mejoras en la batería y los dispositivos se mantendrán frescos, incluso en iOS, pero en Android, es como la noche y el día. Ya puedo ver, ya sabes, KB acercándose a mejoras de casi 16 veces antes los números eran 7.2. Ahora el aumento a 116 FPS, eso es casi 120 FPS. ¿Cuáles son los otros números grandes? De acuerdo, iPhone 11 Pro pasando de 8.8 a 60, eso es casi un aumento de seis veces. Así que en los últimos iPhones, esperamos ver una mejora de 1.8 a 1.2 veces. Pero si observas el uso de la CPU, mostrará una tendencia similar a lo que estás viendo en Android. De acuerdo, de acuerdo. Como me quedan dos minutos antes de terminar, quiero mostrarte una cosa más que es bastante interesante. Hasta ahora hemos estado viendo JSThread.

QnA

Rendimiento de UIThread y Preguntas y Respuestas

Short description:

Flash reduce la carga en UIThread. Las caídas de fotogramas y la congelación de UIThread son comunes con FlatList. FlashList, incluso con grabación, mantiene un alto FPS y evita la congelación de UIThread. Las alturas dinámicas no son un problema con FlashList. No hay preguntas, pero se admiten alturas dinámicas. Comparte tus pensamientos o comentarios.

¿Qué pasa con UIThread? Porque Flash realmente reduce la carga en tu UIThread aún más. Así que puedo hacer eso. En mi dispositivo Android, voy a ir a Configuración, Opciones de desarrollador, perdón, opción equivocada. Hago esto todo el tiempo. Si me desplazo hacia abajo, hay algo llamado como Perfil de renderizado de hardware Ui en pantalla como barras. De acuerdo, volviendo a Expo. Así que primero lanzo lo que comenzamos con nuestro ejemplo original. Esto es con FlatList, tanto vertical como horizontal. Permíteme recargar. Cada vez que veas estas barras que superan la línea roja, eso es una caída de fotogramas, y cuanto más largo sea, peor será. Permíteme ejecutar la prueba y ver cómo va, de acuerdo. Muchas barras altas. Muchas barras altas, y se pausa porque jsthread no puede mantener el ritmo y ni siquiera puede emitir instrucciones para dibujar. Pero tal vez al volver, será mejor. De acuerdo. 1.7 de nuevo, y ves estos enormes picos de fotogramas. Y aquí es donde tu UI también se congela, no solo en blanco, realmente se congela. De acuerdo. Vamos a nuestro ejemplo de FlashList con todo hecho y arreglado. Sí, permíteme recargar. Siempre recargo solo para estar seguro. De acuerdo. Permíteme ejecutarlo, y, de acuerdo. De acuerdo. Incluso con la grabación, verás que permanecemos por debajo de 60 FPS durante bastante tiempo. Por supuesto, estamos perdiendo fotogramas porque es un dispositivo de gama baja, y también estamos grabando o reflejando. Pero sí, si ese no es el caso, entonces es posible, sinceramente, incluso en este dispositivo, si me desconecto del reflejo, hará 60 FPS. Y no tendrás un solo pico enorme que congele tu UIThread en absoluto. Así que eso fue rápidamente algunas notas sobre el rendimiento de UIThread. Voy a desactivarlo rápidamente. De acuerdo. Esto nos lleva al final de la parte de codificación. David, ¿quieres repasar alguna pregunta si tienes alguna? Sí, estaba recordando el chat así que tengo este control deslizante. Pero en caso de que quieras, adelante, levanta la mano aquí si quieres hacer las preguntas aquí. No veo preguntas allí. Veo una pregunta en la sección de preguntas y respuestas aquí. Pero creo que todos- Creo que estabas codificando, así que- Sí, es difícil ir a un lugar aparte, porque fue extremadamente rápido. Pero sí, adelante, levanta la mano, te desmutearemos y podrás hacer tu pregunta. O puedes escribirla en el chat. De acuerdo, ¿cuál era? Es la pregunta de Juan que dice, ¿los elementos pueden tener diferentes tamaños? Creo que respondimos eso en la presentación. Sí, si miras esto ya, ¿verdad? Los elementos tienen diferentes tamaños. ¿Verdad? Flashlist no te pide en ningún lugar, y este es un elemento, como este tweet y el tweet horizontal es en realidad un elemento. Porque lo estamos representando dentro de sí mismo. Y Flashlist no te pide estimaciones diferentes o tamaños fijos en ningún lugar, pero aún funciona muy bien. Entonces, las alturas dinámicas no son un problema en absoluto. ¡Yay! Genial, si quieres compartir tus pensamientos o comentarios, adelante, también puedes hacerlo si no tienes ninguna pregunta. ¡Yay! Pulgar arriba si realmente no tienes preguntas. De acuerdo.

Opiniones del público y Mejoras de rendimiento

Short description:

Ya sea que hayamos hecho algo realmente bueno o realmente malo. Cuanto más compleja sea tu lista, más mejoras verás. En nuestro sitio web, afirmamos una mejora de rendimiento de hasta 10 veces.

Ya sea que hayamos hecho algo realmente bueno o realmente malo. Tal vez pueda hacer una pregunta para el público, como cuántos de ustedes conocen Flashlist antes de esta masterclass o cuántos lo han probado antes de unirse a la masterclass? Tal vez solo den un pulgar hacia arriba también si lo han probado en el pasado, o si es la primera vez que lo ven. Genial. Muy bien. Veo que Zain mencionó que volverá a React Native desde Flutter después de esta masterclass. Eso es una victoria. Sí, y chicos, cuanto más compleja sea su lista, más mejoras verán. En nuestro sitio web, afirmamos hasta 10 veces más, pero pueden superar fácilmente eso si sus elementos son lo suficientemente complejos. Sí, tenemos una lista de secciones. No viene de serie, pero tenemos un tutorial en nuestra documentación que explica cómo usar Flashlist para construir una lista de secciones. Incluso puedes copiar el código de allí si quieres. Pero la lista de secciones no es más que Flashlist con índices de encabezado pegajosos. Además, recientemente lanzamos el diseño de mampostería, algo que Flashlist no tiene. Es como un diseño estilo Pinterest donde los elementos de diferentes tamaños pueden encajar perfectamente, y Flashlist también puede organizarlos automáticamente para que no haya columnas de alturas muy diferentes. Y es bastante rápido. Es tan rápido como tu Flashlist regular, tal vez haya un 1% o 2% más de sobrecarga para calcular todo esto pero aún puedes obtener 120 FPS, 60, puedes aprovechar al máximo tus dispositivos. Muy bien. Muchas personas han oído hablar de ello, pero nunca lo han probado. Espero que ahora lo hagan. Y, ya saben, no duden en hacérnoslo saber o en contactarnos en Twitter para compartir su experiencia. También tenemos una comunidad en Discord donde, si tienen problemas, pueden hacer preguntas, está en nuestro sitio web. Pueden ir allí y preguntarnos, compartir sus ejemplos específicos si necesitan ayuda. Muy bien. Como nota final, sí, gracias a todos por unirse a nosotros. Fue genial realizar esta masterclass junto con Meric, David y Mercy. Nos divertimos mucho viendo estos números y viendo las mejoras que esta biblioteca aporta a todas las aplicaciones y a la comunidad en general. Agradeceríamos mucho si van al repositorio y nos dan una estrella. Amamos nuestras estrellas. Y el documento también tiene a todos los desarrolladores que trabajaron en esta biblioteca. Pueden seguirnos en Twitter si tienen preguntas. Y si obtuvieron buenos resultados hoy, no duden en tuitear sobre ellos y hacer correr la voz porque imagino que mucha gente todavía no sabe sobre esto. Así que si tuitean y difunden la palabra, nos será de gran ayuda a nosotros y a la comunidad. Bien, dejaré de compartir ahora, pero aún tenemos dos minutos si alguien tiene más preguntas. Muy bien. Muy bien entonces. Marci, creo que podemos dejar de grabar. Genial, chicos, siéntanse libres de irse. Hemos terminado por hoy. Gracias por unirse a nosotros. Gracias a todos. Gracias. Nos vemos. Ciao.

Watch more workshops on topic

React Summit 2023React Summit 2023
170 min
React Performance Debugging Masterclass
Featured WorkshopFree
Ivan’s first attempts at performance debugging were chaotic. He would see a slow interaction, try a random optimization, see that it didn't help, and keep trying other optimizations until he found the right one (or gave up).
Back then, Ivan didn’t know how to use performance devtools well. He would do a recording in Chrome DevTools or React Profiler, poke around it, try clicking random things, and then close it in frustration a few minutes later. Now, Ivan knows exactly where and what to look for. And in this workshop, Ivan will teach you that too.
Here’s how this is going to work. We’ll take a slow app → debug it (using tools like Chrome DevTools, React Profiler, and why-did-you-render) → pinpoint the bottleneck → and then repeat, several times more. We won’t talk about the solutions (in 90% of the cases, it’s just the ol’ regular useMemo() or memo()). But we’ll talk about everything that comes before – and learn how to analyze any React performance problem, step by step.
(Note: This workshop is best suited for engineers who are already familiar with how useMemo() and memo() work – but want to get better at using the performance tools around React. Also, we’ll be covering interaction performance, not load speed, so you won’t hear a word about Lighthouse 🤐)
React Advanced Conference 2021React Advanced Conference 2021
132 min
Concurrent Rendering Adventures in React 18
Top Content
Featured WorkshopFree
With the release of React 18 we finally get the long awaited concurrent rendering. But how is that going to affect your application? What are the benefits of concurrent rendering in React? What do you need to do to switch to concurrent rendering when you upgrade to React 18? And what if you don’t want or can’t use concurrent rendering yet?

There are some behavior changes you need to be aware of! In this workshop we will cover all of those subjects and more.

Join me with your laptop in this interactive workshop. You will see how easy it is to switch to concurrent rendering in your React application. You will learn all about concurrent rendering, SuspenseList, the startTransition API and more.
React Summit Remote Edition 2021React Summit Remote Edition 2021
177 min
React Hooks Tips Only the Pros Know
Top Content
Featured Workshop
The addition of the hooks API to React was quite a major change. Before hooks most components had to be class based. Now, with hooks, these are often much simpler functional components. Hooks can be really simple to use. Almost deceptively simple. Because there are still plenty of ways you can mess up with hooks. And it often turns out there are many ways where you can improve your components a better understanding of how each React hook can be used.You will learn all about the pros and cons of the various hooks. You will learn when to use useState() versus useReducer(). We will look at using useContext() efficiently. You will see when to use useLayoutEffect() and when useEffect() is better.
React Advanced Conference 2021React Advanced Conference 2021
174 min
React, TypeScript, and TDD
Top Content
Featured WorkshopFree
ReactJS is wildly popular and thus wildly supported. TypeScript is increasingly popular, and thus increasingly supported.

The two together? Not as much. Given that they both change quickly, it's hard to find accurate learning materials.

React+TypeScript, with JetBrains IDEs? That three-part combination is the topic of this series. We'll show a little about a lot. Meaning, the key steps to getting productive, in the IDE, for React projects using TypeScript. Along the way we'll show test-driven development and emphasize tips-and-tricks in the IDE.
React Advanced Conference 2021React Advanced Conference 2021
145 min
Web3 Workshop - Building Your First Dapp
Top Content
Featured WorkshopFree
In this workshop, you'll learn how to build your first full stack dapp on the Ethereum blockchain, reading and writing data to the network, and connecting a front end application to the contract you've deployed. By the end of the workshop, you'll understand how to set up a full stack development environment, run a local node, and interact with any smart contract using React, HardHat, and Ethers.js.
React Summit 2023React Summit 2023
151 min
Designing Effective Tests With React Testing Library
Featured Workshop
React Testing Library is a great framework for React component tests because there are a lot of questions it answers for you, so you don’t need to worry about those questions. But that doesn’t mean testing is easy. There are still a lot of questions you have to figure out for yourself: How many component tests should you write vs end-to-end tests or lower-level unit tests? How can you test a certain line of code that is tricky to test? And what in the world are you supposed to do about that persistent act() warning?
In this three-hour workshop we’ll introduce React Testing Library along with a mental model for how to think about designing your component tests. This mental model will help you see how to test each bit of logic, whether or not to mock dependencies, and will help improve the design of your components. You’ll walk away with the tools, techniques, and principles you need to implement low-cost, high-value component tests.
Table of contents- The different kinds of React application tests, and where component tests fit in- A mental model for thinking about the inputs and outputs of the components you test- Options for selecting DOM elements to verify and interact with them- The value of mocks and why they shouldn’t be avoided- The challenges with asynchrony in RTL tests and how to handle them
Prerequisites- Familiarity with building applications with React- Basic experience writing automated tests with Jest or another unit testing framework- You do not need any experience with React Testing Library- Machine setup: Node LTS, Yarn

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

React Advanced Conference 2022React Advanced Conference 2022
25 min
A Guide to React Rendering Behavior
Top Content
React is a library for "rendering" UI from components, but many users find themselves confused about how React rendering actually works. What do terms like "rendering", "reconciliation", "Fibers", and "committing" actually mean? When do renders happen? How does Context affect rendering, and how do libraries like Redux cause updates? In this talk, we'll clear up the confusion and provide a solid foundation for understanding when, why, and how React renders. We'll look at: - What "rendering" actually is - How React queues renders and the standard rendering behavior - How keys and component types are used in rendering - Techniques for optimizing render performance - How context usage affects rendering behavior| - How external libraries tie into React rendering
React Summit Remote Edition 2021React Summit Remote Edition 2021
33 min
Building Better Websites with Remix
Top Content
Remix is a new web framework from the creators of React Router that helps you build better, faster websites through a solid understanding of web fundamentals. Remix takes care of the heavy lifting like server rendering, code splitting, prefetching, and navigation and leaves you with the fun part: building something awesome!
React Advanced Conference 2023React Advanced Conference 2023
33 min
React Compiler - Understanding Idiomatic React (React Forget)
React provides a contract to developers- uphold certain rules, and React can efficiently and correctly update the UI. In this talk we'll explore these rules in depth, understanding the reasoning behind them and how they unlock new directions such as automatic memoization. 
React Advanced Conference 2022React Advanced Conference 2022
30 min
Using useEffect Effectively
Top Content
Can useEffect affect your codebase negatively? From fetching data to fighting with imperative APIs, side effects are one of the biggest sources of frustration in web app development. And let’s be honest, putting everything in useEffect hooks doesn’t help much. In this talk, we'll demystify the useEffect hook and get a better understanding of when (and when not) to use it, as well as discover how declarative effects can make effect management more maintainable in even the most complex React apps.
React Summit 2022React Summit 2022
20 min
Routing in React 18 and Beyond
Top Content
Concurrent React and Server Components are changing the way we think about routing, rendering, and fetching in web applications. Next.js recently shared part of its vision to help developers adopt these new React features and take advantage of the benefits they unlock.In this talk, we’ll explore the past, present and future of routing in front-end applications and discuss how new features in React and Next.js can help us architect more performant and feature-rich applications.
React Advanced Conference 2021React Advanced Conference 2021
27 min
(Easier) Interactive Data Visualization in React
Top Content
If you’re building a dashboard, analytics platform, or any web app where you need to give your users insight into their data, you need beautiful, custom, interactive data visualizations in your React app. But building visualizations hand with a low-level library like D3 can be a huge headache, involving lots of wheel-reinventing. In this talk, we’ll see how data viz development can get so much easier thanks to tools like Plot, a high-level dataviz library for quick & easy charting, and Observable, a reactive dataviz prototyping environment, both from the creator of D3. Through live coding examples we’ll explore how React refs let us delegate DOM manipulation for our data visualizations, and how Observable’s embedding functionality lets us easily repurpose community-built visualizations for our own data & use cases. By the end of this talk we’ll know how to get a beautiful, customized, interactive data visualization into our apps with a fraction of the time & effort!