En esta 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 mínimo esfuerzo. Usaremos 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 categoría.
Sabrás:
- Breve presentación sobre qué es FlashList, por qué lo construimos, etc.
- Migrando de FlatList a FlashList
- Enseñando cómo escribir una lista performante
- Utilizando las herramientas proporcionadas por la biblioteca FlashList (principalmente el hook useBenchmark)
- Usando los plugins de Flipper (gráfico de llamas, nuestro perfilador de listas, perfilador de UI & JS FPS, etc.)
- Optimizando el rendimiento de FlashList utilizando props más avanzados como `getType`
- 5-6 tareas de muestra donde descubriremos y solucionaremos problemas juntos
- Preguntas y respuestas con el equipo de Shopify
This workshop has been presented at React Advanced Conference 2022, check out the latest edition of this React Conference.
FAQ
FlashList es una versión mejorada del componente FlatList de React Native desarrollada por Shopify. Está diseñada para optimizar el rendimiento de las listas en aplicaciones, minimizando los elementos vacíos y mejorando la experiencia del usuario en dispositivos de gama baja.
FlashList ofrece una mejor gestión de memoria, minimizando la renderización desde cero y reutilizando elementos a través de un Recycling Pool. Además, soluciona problemas de diseño de primer renderizado y es capaz de manejar alturas dinámicas de forma más eficiente.
El Recycling Pool en FlashList permite que los elementos que ya no son visibles en la pantalla se almacenen temporalmente. Cuando se necesita cargar más elementos, FlashList reutiliza los elementos del Recycling Pool, actualizándolos con nuevos datos, lo que reduce la necesidad de renderizaciones completas y mejora el rendimiento.
Sí, FlashList ya está siendo utilizado en producción en varias aplicaciones de Shopify, como Shopify Mobile Shop, POS e Inbox. Ha demostrado ser eficaz en mejorar significativamente el rendimiento en dispositivos de gama baja.
Puedes revisar y contribuir al proyecto FlashList en GitHub, donde está disponible como código abierto. También puedes unirte a la comunidad de Shopify en Discord para discutir y obtener ayuda sobre FlashList.
Antes de desarrollar FlashList, se consideró RecyclerListView, una biblioteca popular de código abierto. Sin embargo, debido a su API complicada y dificultades con alturas dinámicas de celdas, Shopify decidió crear su propia solución optimizada.
Durante la masterclass se utilizó un plugin de Flipper específicamente diseñado para el proyecto, que ayuda a monitorear y visualizar el rendimiento de FlashList, como las tasas de FPS y los espacios en blanco en las listas.
FlashList es una alternativa a FlatList de React Native que busca alto rendimiento y facilidad de uso. Proporciona mejoras significativas en el rendimiento sobre FlatList, con mayor JSFPS y UIFPS. FlashList ha sido implementado con éxito en las aplicaciones Mobile Shop, POS e Inbox de Shopify. La 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.
¡Hola a todos! Mi nombre es Marek, ingeniero de software en Shopify en Berlín. Presentaré FlashList y luego pasaré la palabra a Talha. Talha Nikwi, un gerente de desarrollo en Shopify, te guiará a través de la masterclass. 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 deficiencias, como una API complicada y dificultades con las alturas dinámicas.
Hola a todos, mi nombre es Marek. Soy ingeniero de software en Shopify, y estoy basado en Berlín. Y estaré haciendo una presentación como introducción a FlashList, y luego se la pasaré a Talha para liderar el resto de la masterclass. Así que si quieres presentarte también.
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 para nuestra aplicación POS. Tuve la oportunidad de colaborar con Marek y David en el proyecto FlashList. Y te guiaré a través de la masterclass después de que Marek termine hoy. Gracias. Y luego David estará aquí para apoyarnos, así que si quieres dar una rápida introducción también.
Sí. Gracias, Marek. Soy David. Soy de Barcelona, España. Veo a algunas personas de España también en la audiencia. Me alegra verlo. Soy un gerente de desarrollo aquí en Shopify desde hace un año y formé parte del equipo de FlashList y estoy orgulloso de mostrarles esto hoy porque es un proyecto en el que fue muy agradable trabajar y ver el impacto que está teniendo en la comunidad. Así que sí. Estoy contento de estar aquí hoy.
Perfecto. Entonces, sin más preámbulos, compartiré mi pantalla para pasar por 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 daré una breve introducción al tema de esta masterclass que es FlashList. Así que permíteme comenzar con un tweet aquí. ¿Qué pasaría si React Native termina reteniéndonos. Nos retiene. ¿Dónde estás renderizando? Una lista de tarjetas con checks en ellas. Ahora, por supuesto, esto es un poco de exageración, pero te da una idea de cómo se perciben las listas en React Native y eso es dentro de React Native comunidad pero también fuera. Además, hemos tenido nuestra parte de problemas con FlatList, el componente predeterminado que viene de React Native. Esta es nuestra aplicación de tienda funcionando en un dispositivo Android de gama baja. Como puedes ver, no es nada receptivo y tiene muchas celdas en blanco que a veces abarcan 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 lo implementas correctamente. Y la API es altamente personalizable, por lo que puedes lograr casi cualquier cosa con ella. Y es también bastante bien probado. Se ha utilizado durante varios años en empresas más grandes. Y ha resistido bien. Pero también tiene un par de deficiencias. Principalmente, la API la API es realmente complicada, lo que lleva a una experiencia de desarrollador menos que deseable. Es también bastante difícil lograr celdas de rendimiento con alturas dinámicas. Y además, debido al hecho de que Recycler's View es una implementación solo de JS, hay espacios de diseño de primer render que no deberían estar allí.
2. Implementación y rendimiento de FlashList
Short description:
Construimos nuestra propia versión llamada FlashList para abordar las deficiencias de FlatList. FlashList apunta a altas tasas de fotogramas, una visualización mínima de elementos vacíos y facilidad de uso. Utiliza una API similar a FlatList pero introduce props para un mejor rendimiento. FlashList utiliza un Recycling Pool para administrar eficientemente la representación de elementos, ahorrando recursos. También solucionamos el problema del primer diseño de renderizado con la Vista de Diseño Automático. 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 sobre FlatList.
Entonces, estas deficiencias significaron para nosotros que realmente necesitábamos construir nuestra propia versión en Shopify y la llamamos FlashList. Los objetivos de los proyectos han sido lograr una alta tasa de fotogramas tanto para UI como para JSFPS. Queríamos minimizar tanto como fuera posible la visualización de elementos vacíos y queríamos hacer que la biblioteca fuera realmente fácil de usar y lograr tanto rendimiento como pudiéramos para una experiencia de desarrollador realmente fluida.
Entonces, esta es la API para FlashList que hemos ideado y como puedes notar, hemos cambiado principalmente el nombre del componente de FlatList a FlashList y tratamos de mantener la gran mayoría de las props iguales. Ahora, hay algunas props en FlashList que no existen en FlatList para lograr un mejor rendimiento, y aprenderás sobre algunas de ellas más adelante en la masterclass. Las alturas dinámicas no suponen ningún problema y, como mencioné, eso es incluso con el tipo de API de FlatList. Entonces, permíteme responder a una pregunta ahora, ¿cómo es FlashList tan rápido? Y comenzaré explicando cómo funciona FlatList primero. Entonces, en FlatList, tenemos un par de elementos que están en el viewport aquí, índices del cuatro al seis, luego tenemos un par de elementos precargados que están en la parte inferior de la lista. Y luego tenemos un par de elementos que todavía están cargados en memoria, dos a tres. Ahora, la cantidad de elementos en memoria en el caso de FlatList es bastante alta. Pero a medida que te desplazas hacia abajo lo suficiente, FlatList necesitará liberar algo de espacio en la memoria. Y ahí es cuando entra en juego el componente VirtualizedList que FlatList usa debajo del capó. Y lo que hará es que a medida que te desplazas hacia abajo, vaciará los elementos, de modo 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, también siempre tendrás que renderizar estos elementos desde cero, lo que consume muchos recursos. Como visualización, aquí puedes ver celdas con sus ID de instancia. Y a medida que nos desplazamos hacia abajo, simplemente obtenemos más y más ID, lo que significa que podemos obtener más y más instancias. Y de nuevo, todo necesita ser renderizado desde cero. Entonces, para resumir, Flando usa esta lista virtualizada debajo del capó. Y a medida que te desplazas, reemplaza las celdas con contenido vacío. Y lo importante a tener en cuenta es que las celdas siempre se renderizan desde cero, a menos que estén en memoria, lo que consume, de nuevo, muchos recursos. Las plataformas, por otro lado, adoptan un enfoque diferente. Nuevamente, tenemos un par de elementos en el viewport. Tenemos algunos elementos que están precargados, pero la cantidad de esos elementos es bastante baja. Y lo más importante, tenemos un concepto llamado Recycling Pool. Entonces, 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 mirará en el Recycling Pool, y si hay algún elemento que actualmente no está en uso, moverá ese elemento de vuelta a la lista y simplemente lo volverá a renderizar con los nuevos datos. Esto significa que, por ejemplo, si solo cambia un texto en la celda, tendrá que volver a renderizar solo esa parte, y no tendrá que crear nada desde cero. Y eso lo hace bastante eficiente. Como visualización, puedes ver cómo a medida que nos desplazamos, los elementos se van colocando en el recycling pool, y luego, cuando necesitamos crear más elementos en la parte inferior de la lista, FlashList comenzará a sacar los elementos del recycling pool de vuelta a la lista, y comenzaremos a obtener instancias e ID que hemos visto antes. Y de nuevo, esto ahorra muchos recursos. También necesitábamos solucionar el problema del primer diseño de renderizado. Entonces, así es como se veía el problema del primer diseño con Recycle List View, y puedes ver que los elementos se superponen entre sí. Ahora esto es solo por un par de fotogramas, por lo que esta grabación se ralentiza para hacer esto más obvio. Para profundizar en el problema, en el lado izquierdo, tienes cómo Recycle List View espera que se vea el diseño. Espera que cada elemento sea el mismo dependiendo también del tamaño estimado del elemento, que es un problema del que también aprenderemos más adelante en la masterclass. Pero el diseño real, lo que realmente se renderiza 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 todavía cuenta con que solo tiene 100. Y entonces el elemento número dos está entonces sobre el elemento número uno, lo que resulta en elementos que se superponen entre sí. Entonces, 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 UI y coloca todo de borde a borde como se supone que debe ser. Entonces, con FlashList, si miramos la grabación, podemos saber cómo. Para resumir la implementación de FlashList, tenemos una API que es muy similar a FlatList. Hemos implementado una vista nativa para solucionar el problema del primer renderizado. Hemos podido lograr una altura de celda dinámica de alto rendimiento con la API simple similar a FlatList y hemos utilizado Recycle como el motor interno en el que hemos construido para lograr la API.
3. Rendimiento de FlashList y Configuración de la Masterclass
Short description:
FlashList proporciona mejoras significativas de rendimiento sobre FlatList. Logra un JSFPS y UIFPS más altos, lo que resulta en una interfaz de usuario más receptiva. El plugin 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 da más performance de serie. Así que vamos a echar 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 cuando veas los números.
Primero veamos el FlatList UI en JSFPS usando la muestra 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 a menos de 10 también. Así que lo que obtenemos al final es un JSFPS promedio de 11.8, un UI promedio de 44 y el bloqueo del hilo JS es casi dos segundos, lo que significa que durante casi dos segundos el usuario no ha podido interactuar con la pantalla en absoluto porque cuando el JS está en el bloqueo del hilo eso no es posible.
Si miramos el FlatList UI en JSFPS con la misma muestra simplemente cambiando el nombre, podemos ver que el JSFPS nunca cae tan bajo, nunca cae ni siquiera cerca de ser cero, y el UIFPS se mantiene alrededor de 64 la mayor parte del tiempo. Así que obtenemos un JSFPS promedio de 49 y un UIFPS promedio de 58, lo que es una mejora de cuatro veces simplemente cambiando el nombre.
También hemos estado mirando los espacios en blanco usando un plugin de Flipper que hemos construido solo para este proyecto. Y como puedes ver con FlatList, obtenemos enormes celdas en blanco que abarcan toda la pantalla, que son las partes realmente grandes en la parte superior, y el promedio es de alrededor de 280 píxeles. Con FlatList, obtenemos una historia diferente. Sí obtenemos algunas celdas en blanco, pero son bastante limitadas y sólo aparecen durante un período limitado de tiempo, y así el promedio al final es de alrededor de 45, o así, lo cual es siete veces mejor que con FlatList.
Entonces, ¿está FlashList 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 respondía en absoluto, y tenía esas enormes pantallas en blanco que abarcaban toda la pantalla. Y a la derecha, tenemos algunas celdas en blanco pequeñas, pero sólo durante un período limitado de tiempo, y lo más importante, la aplicación es extremadamente rápida, incluso en un dispositivo Android de gama baja como el Moto G10. También lo estamos usando en todas nuestras aplicaciones en Shopify Mobile Shop, POS, e Inbox. Y también hemos visto mucha emoción en la community, y la lista también está siendo usada extremadamente ahora en producción también. Así que puedes revisar el proyecto en GitHub, pero también lo harás durante esta masterclass. Y eso es todo por mi parte. Y se lo pasaré 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. Yo me encargo a partir de aquí. Permíteme empezar presentando mi pantalla. Bien. Segundo. Vale. Entonces, antes de comenzar, voy a presentar rápidamente a todos— Bien, incluso antes de empezar, ¿puedo obtener algunos pulgares arriba en el chat si todos pueden oírme bien? Y si estás aquí, sólo para que me lo hagas saber. Genial. Genial, veo algunas respuestas. Bien. Bien. Vale. Entonces, estoy compartiendo un documento en el chat ahora mismo. Asegúrate de usar este enlace y abrir este documento. Así es como se ve. Está justo aquí en mi pantalla. Así que básicamente estos son todos los pasos de configuración que tenemos para ti. Voy a repasar cada uno de ellos. Sólo quiero darte una rápida visión general de lo que puedes hacer en caso de que te encuentres con problemas. Así que, en primer lugar, hay un enlace para preguntas. Asegúrate de usar este enlace para hacernos preguntas y no el chat. Vamos a intentar pasar por la mayoría de ellas hacia el final de esta masterclass. Hay un enlace a una hoja de seguimiento de performance, de la que voy a hablar muy pronto. Tienes un enlace a las diapositivas que voy a presentar. Lo más importante, hay esta sección llamada saltar adelante. Así que, en cualquier momento, digamos, si no has podido completar una tarea en particular, puedes saltar a cualquier tarea que quieras. Digamos, si saltas a la tarea cuatro, la tarea uno, dos, tres ya estará hecha en ese snack para ti ya. Así que, no te preocupes si no eres capaz de seguir el ritmo, puedes saltar adelante, y puedes hacerlo a tu ritmo, en tu propio tiempo más tarde.
4. Introducción a la Masterclass y Benchmark
Short description:
Comencemos con la masterclass. Asegúrate de tener instalado Expo Go y abre el enlace proporcionado. Conecta tu teléfono escaneando el código QR. Abre la hoja de seguimiento de rendimiento y añade tu nombre y dispositivo. La muestra 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 Benchmark y espera el resultado del FPS promedio.
Muy bien. Entonces, sin más preámbulos, ¿empezamos con la masterclass, verdad? Comenzaré a presentar.
Muy bien. Asegúrate de tener Expo Go instalado en tu teléfono. Y asegúrate de abrir, este, el enlace que se menciona en el documento aquí, abre el siguiente escaneo, puedes abrir esto, y verás algo así. También voy a escanear este código QR y asegurarme de que mi teléfono está conectado. Asegúrate de escanear tu código QR y no el mío. Entonces, aquí vamos. Puedes ver mi dispositivo a la derecha, es el Moto G Stylus. Vale. Entonces, tengo mi dispositivo conectado en este punto. Puedes ver que este dispositivo aparece en Snap. Puedo hacer clic en el botón de recargar la aplicación para recargar en cualquier momento. Y a la izquierda, puedes hacer clic en los errores y una advertencia y registros para ver los registros que van a aparecer. Esa fue una rápida introducción de cómo va a funcionar Snap.
Bien. Como segundo paso, vuelve al documento y abre la hoja de seguimiento de rendimiento. Se verá algo así. Entonces, lo que quiero que haga todo el mundo después de haber lanzado la muestra y poder verla en su aplicación ExpoGo, es que vayan y hagan clic en esta casilla y añadan su nombre y dispositivo a la izquierda. Así es como podemos llevar un seguimiento de cómo va progresando todo el mundo. Joshua, asegúrate de que tu aplicación ExpoGo está actualizada. Muy bien. Adelante, añade tus nombres. Muy 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 problemas? Adelante, adelante. Sí, no te preocupes por el resto de las columnas. Te voy a explicar exactamente qué vamos a hacer, y lo haremos juntos. Solo añade tus nombres, tu dispositivo, y si has cargado la muestra en tu aplicación Xpogo. Muy bien, vamos a explorar rápidamente de qué trata la muestra, y luego empezaremos con la primera tarea. Esta muestra es una lista de feeds de Twitter, y algunos de estos tweets tienen tweets relacionados con ellos. Así que si te das cuenta, cualquier cosa que tenga más de dos retweets tiene un tweet relacionado. Así que es una combinación de listas verticales y listas horizontales. Si haces clic en cualquiera de los elementos horizontales, va a cambiar el tweet principal. Y el elemento se va a seleccionar. Y eso es todo lo que hace esta muestra. Siéntete libre de jugar con ella.
Entonces, pasando a la siguiente tarea, y empezaremos a hacer cosas ahora. Muy bien, ¿cuál es la primera cosa? Entonces, lo que queremos hacer es, si te das cuenta, hay un botón Ejecutar Benchmark en la parte superior. Quiero que todos hagan clic en él y esperen a que el benchmark se ejecute y termine. Te va a dar un número de FPS promedio al final de la ejecución. Lo haré contigo. Hagámoslo juntos. Muy bien. Vale, el mío está corriendo. Vale, así que obtuve un resultado. Mi AFPS promedio fue de 1.7. Recuerda, el mío es un dispositivo bastante básico. Es un Moto G Stylus con un Snapdragon 665.
5. Finalización del Benchmark y Siguiente Paso
Short description:
Después de completar el benchmark, introduce el número promedio en la columna de línea de base. Asegúrate de recargar la aplicación y elige el enlace correcto si es necesario. El número de rendimiento depende del dispositivo utilizado. Las listas verticales y horizontales anidadas pueden ser complejas. Por favor, asegúrate de que estás utilizando la muestra correcta. Pasemos al siguiente paso.
Entonces, después de que hayas terminado, lo que quiero que haga todo el mundo es ir y poner este número promedio en la columna de línea de base. Solo tienes que hacer clic en ese botón de ejecutar benchmark y esperar. Muy bien, muy bien. Mucha gente ha podido hacerlo. Recuerda, tienes que 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 que has elegido el enlace correcto y simplemente ejecuta el benchmark de nuevo, y puedes actualizarlo más tarde. Sí, este número depende efectivamente del rendimiento del dispositivo, y yo estoy usando un dispositivo de gama muy baja, Moto G Stylus, Snapdragon 665. En la lista plana, todos los elementos están memorizados. Todo está como debería estar. Es solo que cuando tienes una lista vertical y una lista horizontal anidadas juntas, es algo bastante complejo. ¿Ah, eso qué es? Has abierto directamente la muestra final. Muy bien, Joshua, asegúrate de arreglarlo. Así que seguiremos adelante en interés del tiempo porque realmente quiero responder a las preguntas al final.
6. Resumen de la Muestra e Inicio de la Migración
Short description:
Echemos un vistazo a la muestra e iniciemos la migración a FlashList. Cambia el nombre a FlashList e impórtalo. Recarga la aplicación. Primer paso para la migración completado.
Bien, ¿cuál es el siguiente paso? Lo que queremos hacer ahora es, vamos a mirar la muestra, ¿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 haga todo el mundo es comenzar su migración a FlashList. Voy a hacer las primeras cosas con ustedes, así que sigan, pero el resto de las tareas, podría pausar por un minuto o dos y dejar que lo hagan ustedes. Así que lo que necesitamos hacer es, necesitamos cambiar el nombre a FlashList, y necesito importarlo. Muy bien. Eso es todo. Cambia el nombre a FlashList, y voy a seguir adelante y recargar la aplicación. Vale. Y eso es todo. Hemos completado el primer paso para la migración 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 la siguiente cosa 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 tardan tus elementos en hacerse visibles en la pantalla y FlashList tiene una API ordenada que te permite hacer eso. Así que, voy a hacer eso. Por supuesto, estoy copiando y pegando algo de code, pero siéntete libre de escribirlo.
Así es como se hace. Añades un oyente de carga. Te da un objeto del cual puedes seleccionar el tiempo transcurrido en milisegundos y puedes registrarlo. Así que, permíteme recargar la aplicación de nuevo y verás que tendremos un tiempo de carga que aparecerá. Muy bien. Entonces, mi tiempo de carga para esta lista es 1319. Realmente enorme. Está tardando más de un segundo en renderizarse. Si te das cuenta, FlashList nos está dando una advertencia aquí. Está diciendo que el tamaño estimado del elemento no está definido. Y basado en la configuración actual, puedo establecerlo en 279 para optimizar el performance.
¿Qué significa esto? Entonces, antes de renderizar, FlashList generalmente tiene que hacer una suposición sobre 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 es de 100 píxeles. Pero después de renderizar, como desarrollador, ahora sé que mis elementos son de 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, tendremos que hacer el tamaño estimado del elemento, 279. Una vez que he hecho eso, permíteme recargar la aplicación de nuevo. Esperemos a que aparezca el tiempo de carga. Muy bien. Mi tiempo de carga ahora es de 485 milisegundos. ¿Qué pasó aquí? FlashList pudo hacer una suposición mucho mejor sobre cuántos elementos requiere al principio. Eso llevó a un número menor de elementos montados. Y, si ves, 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 arriba si has podido hacer esto. Pulgar arriba. Hecho. ¿Algo en el chat? Genial. Estoy viendo algunas cosas aparecer. Eso es genial. Muy bien. Entonces, repitamos lo que hicimos la primera vez. Vamos a hacer clic en Ejecutar Benchmark Juntos en el code actualizado y registraremos los números bajo la tarea 1. Permíteme hacerlo. Muy bien. Está corriendo para mí. Muy bien. Todo está blanco. Vale. El JSFES ahora es solo de 2.9. Todavía bastante malo. Voy a seguir adelante y protegerlo bajo 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. Utilizaremos un fragmento de código y recargaremos la aplicación para observar los eventos. Una vez que tengamos los datos, ejecutaremos el benchmark de nuevo. Recuerda comentar el console.log para evitar el impacto en el rendimiento.
Vale. Me alegra ver que muchos de ustedes pueden hacer esto. Asegúrate de que estás eligiendo el número promedio y no los máximos o mínimos.
OK. Bien, pasando a la tarea dos. Correcto, lo que queremos hacer es, como Merrick describió, el objetivo de FlashList es reducir el número de elementos que se están creando y destruyendo. Entonces, ¿cómo podemos observar eso? Podemos usar el siguiente fragmento de code dentro de nuestra celda de tweet y elementos de contenido de tweet.
Y, bien, Mia, puedes simplemente hacer clic en el enlace aquí y la tarea uno ya estaría hecha para ti. Y puedes simplemente comenzar con la tarea dos si no pudiste terminarla. Pero si necesitas unos minutos extra, adelante y tómalos. Bien. OK. Entonces, vamos a hacer esto. Entonces, primero voy a ir a la celda de tweet y. Yo. Use effect. Y. Use effect. Y voy a devolver una función aquí. Que va a. Tomar console log. Ellos console en log. Celda de tweet. Estoy fuera. Y solo queremos que esto se ejecute solo cuando los componentes y los meses pasaré un array de dependencia vacío. Un pedazo de code muy simple.
Y lo mismo copiaré. Y pegaré dentro del contenido del Tweet. Eso está en la línea 72. Y voy a cambiar mi console a contenido de Tweet. Y voy a importar use effect. Adelante, tómate tu tiempo. No hay prisa. Así que ya terminé. Voy a recargar la aplicación ahora. Dame un pulgar arriba si has hecho esto. Genial. Genial, genial, genial. Vale, vale, observemos. Borraré los registros existentes. Veamos. Voy a desplazarme manualmente, y vale. Ves que nuestra celda de tweet se está desmontando todo el tiempo. El contenido del tweet también se desmonta. Muchos eventos de montaje y desmontaje, y esto es algo que realmente queremos evitar. Bien, entonces la idea de esta tarea en particular era simplemente observar cuántos montajes y desmontajes tenemos, y luego simplemente ejecutar el benchmark una vez más. Así que hagamos eso.
9. Console Log, Key Prop y Flashlist
Short description:
Comenta console.log, recarga la aplicación, ejecuta el benchmark. Los resultados pueden variar en dispositivos Android de gama baja. Tarea 3: Eliminando las claves asignadas en Flashlist. Las claves a menudo se agregan en Flatlist, pero en Flashlist, pueden marcar una gran diferencia. Elimina una clave del elemento de renderizado 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 al performance. Pero vamos a descomentarlo en la siguiente tarea. Así que voy a comentar console.log, recargar la aplicación, esperar a que se cargue. Y vamos a ejecutar el benchmark de nuevo. Vale, para mí el resultado es 8.9 FPS. ¿Verdad? Creo que no hizo mucho para, ya sabes, cambiar la performance 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 pasó porque ciertamente no hice ningún cambio para mejorar nada. Vale. Así que vamos a capturar esos resultados. Muchos de vosotros estáis en 41, 47, 44 ya, 56. Sí. Quiero decir, iPhone 13 y iPhone 14 Pros, tienen un rendimiento de un solo núcleo realmente sólido. Por eso pueden simplemente forzar su camino a través de algunos de estos problemas de rendimiento. Pero son mucho más visibles en dispositivos Android de gama baja, incluso en dispositivos Android de gama media. Creo que eso es lo que va a 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 sospechas, simplemente activa una recarga ya sea desde la consola web o agitando el dispositivo y usando el botón de recarga. Muy bien. Procedamos. ¿Cuál es la tarea 3? Quería hablar rápidamente sobre la función de la prop key y react. Cuando key prop básicamente mapea tu instancia JS a una instancia UI real en el DOM, y cada vez que cambias una clave en React, va a recrear tanto el nodo UI como el nodo JS. Esto es específicamente lo que queremos evitar en Flashlist. La siguiente tarea trata sobre averiguar dónde se han asignado explícitamente estas claves, y vamos a eliminarlas y ver su impacto en las operaciones de montaje y desmontaje que están ocurriendo. Hemos observado que en muchos casos, cuando estás usando Flatlist, tiendes a agregar estas claves, porque no se ve realmente afectado por ello. Está destruyendo y recreando de todos modos, así que tenerlo o no tenerlo no hace 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, así que si vas a Twitter, verás que el elemento de renderizado principal tiene una clave explícita definida. Lo que queremos hacer es ir y eliminarla. Eso es todo. Y también queremos volver a la celda del tweet y de nuevo descomentar nuestro oncehold.log para que podamos observar de nuevo los eventos de desmontaje. Esa era la primera clave. Adelante e intenta encontrar la otra clave si está definida en algún lugar. Y déjame saber dónde está en el chat. Podría estar en cualquiera de estos componentes. Esperaré un minuto y luego procederemos. Vale, parece que la gente ha encontrado donde, donde está la clave. Sí, está dentro del contenido del tweet. y está en la línea número 78. Si ves esto, esto, esta clave ni siquiera es parte de ninguna declaración de mapa. Realmente no se requiere a menos que alguien explícitamente quisiera destruir y recrear este elemento. Así que podemos seguir adelante, eliminarlo. Recarguemos la aplicación. Vale, déjala recargar. A veces tarda un poco incluso después de que aparece. Ahora sí se recargó. Vale, déjame desplazarme.
10. Solucionando el Problema de Desmontaje y Ejecutando el Benchmark
Short description:
El contenido del tweet todavía se está desmontando, pero la celda del tweet ya no se está desmontando. Esto se debe a que eliminamos la prop key definida en la celda del tweet. Resolveremos el problema del desmontaje del contenido del tweet pronto. Vamos a eliminar el use effect para rastrear los desmontajes y comentar el desmontaje del contenido del tweet. Luego, volveremos a ejecutar el benchmark para verificar si hay alguna mejora.
Correcto. Si te das cuenta, el contenido del tweet todavía se está desmontando, pero la celda del tweet ya no se está desmontando en absoluto. Como que no veo un solo registro allí. Y la razón es porque eliminamos la prop key que estaba definida en la celda del tweet. Así que el único problema que tenemos ahora mismo es el desmontaje del contenido del tweet, y vamos a averiguar cómo resolver eso muy pronto. Así que dado que la celda del tweet ya no se está desmontando, voy a seguir adelante y eliminar este use effect para rastrear los desmontajes. Y como hicimos la última vez, voy a comentar el desmontaje del contenido del tweet, porque va a interferir con nuestros benchmarks. Así que comenta eso, recarga, vamos a hacerlo. Y luego vamos a ejecutar el benchmark de nuevo y ver si tenemos alguna mejora.
11. Resultados del Benchmark y Tarea Cuatro
Short description:
La lista se cargó en 491 milisegundos. Alguna mejora, pero aún no es genial. Pasemos a la tarea cuatro.
Bien, déjalo recargar. Bien, mi lista se cargó, 491 milisegundos, dame un pulgar arriba si estás listo para ejecutar el benchmark. Bien, muy bien. Hagámoslo. Oh, todavía se está quedando en blanco. Si te das cuenta, mi Moto G stylus se queda totalmente en blanco en la mayoría de las ejecuciones. Está bien, 11.6. Entonces, en mi caso, tengo una pequeña mejora, pero nada importante para realmente celebrar. Todavía es bastante malo, ¿verdad? Adelante, termina tus benchmarks y luego pasaremos a la tarea cuatro. Aquí es donde creo que las cosas van a empezar a ponerse interesantes. Sí.
12. Solucionando el 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 USE Effect. 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. Vamos a ejecutar el benchmark de nuevo y analizar los resultados.
Bien, ya 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. Bien, déjame mostrarte. Mira los elementos superiores. El primer tweet es de Chris, el segundo es de Lorenzo. Sí, alguien lo ha notado. Los elementos se están repitiendo. Si vuelvo a la parte superior de nuevo, los tweets han cambiado. ¿Por qué está pasando esto? Esto está sucediendo porque los elementos se están reciclando y cuando se reciclan, no se actualizan. Sé que esto también podría ser la razón por la que mi performance ha mejorado. Porque no está pasando nada, los elementos simplemente se están moviendo. Así que rápidamente te mostraré lo que está pasando y por qué esto es un problema y cómo podemos solucionarlo y luego lo solucionaremos juntos. Si te has dado cuenta, a cada celda, te dije, que cuando haces clic en uno de los elementos horizontales, cambia el tweet de nivel superior. Y este tweet actual se mantiene usando un estado, siempre que ese clic ocurre, el estado se actualiza. Pero cuando el elemento realmente se recicla, el estado no cambia, por lo que el tweet actual se conserva y ese es 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. Bien, es nuestro hook favorito, USE Effect. Déjame mostrarte cómo puede funcionar. Este es el fragmento de code que vamos a usar. Entonces, lo que necesitamos hacer es, hagámoslo juntos. USE Effect. 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. Así que, 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 code, use effect si currentTweet no es igual a tweet, setCurrentTweet, y formatea para que quede claro. Voy a recargar. Bien, se ha recargado. Así que mis dos primeros tweets son de Aaron y de Gargley. Y déjame desplazarme. No estoy seguro de si estoy pronunciando bien sus nombres, pero perdónenme. Si vuelvo a subir, verás que ahora todo está bien. No hay elementos que se repiten. ¿Todos han podido solucionar el problema? Dame un pulgar arriba si ya lo has solucionado. Bien. Genial, me alegra ver que todos pueden seguir el ritmo fácilmente. Al principio estábamos bastante aprensivos, la verdad ¿es demasiado difícil? Incluso hicimos una prueba ayer solo para asegurarnos de que no fuera demasiado difícil. Bien, si todos están listos, vamos a ejecutar el benchmark de nuevo. Y veamos los resultados. Estamos añadiendo otra renderización. Así que podría ralentizarse. Descubrámoslo. Mientras tanto, ¿puede alguien decirme si esta quizás no es la mejor manera de actualizar el elemento y cuál podría ser el problema potencial? Bien, si ves mis números han disminuido a 6.6. No veo una gran mejora. Bien. Oh, todo el mundo ya está más allá del 50% con lo que puse en mis números. Eso es genial. Me alegra ver esto. Bien.
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 resulta en que el elemento no se destaca cuando se hace clic. Podemos solucionar esto utilizando la propiedad extra data para pedir a FlashList que vuelva a renderizar cuando cambia 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. Vamos a ejecutar el benchmark de nuevo para verificar los nuevos números de rendimiento.
Bien, sigamos adelante. Tarea número cinco. Si te das cuenta, la lista horizontal también es una flat list. Así que lo que queremos hacer es queremos migrar eso a FlashList y queremos buscar errores. Así que adelante y hazlo. De nuevo, cuando migres, te dará una sugerencia para un tamaño de elemento estimado. Voy a esperar un minuto para que todos lo hagan antes de que yo también lo haga, de acuerdo. Y luego discutiremos el error y cómo podemos solucionarlo.
Bien, hagamos 40 segundos. No debería llevar mucho tiempo y luego lo haré. También trata de descubrir o notar cualquier error si lo hay. Bien, también empezaré a hacerlo. Tengo que ir a tweets cell. Cambiaré flat list a flash list. Necesito importarlo, importar flash list de ese Shopify flash list. Voy a recargar ahora. Y espero que me dé una sugerencia para mi tamaño de elemento estimado porque no quiero adivinarlo ahora mismo. Bien, tengo una sugerencia, es 352. Permíteme seguir adelante y agregar ese tamaño de elemento estimado 352 y recargar una vez más. ¿Alguien ve algún problema? Algunos elementos pueden repetirse en la lista horizontal porque estamos generando aleatoriamente esas recommendations, pero la repetición no es el problema.
Bien, 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, verías aparecer un borde azul claro. Eso ya no está sucediendo, aunque está funcionando. Entonces, ¿por qué es eso? La razón de eso es que FlashList es extremadamente agresivo en reducir las renderizaciones. Así que en lugar de optar por no volver a renderizar usando use memo y cosas así, más bien optas por volver a renderizar. Así que si tus data han cambiado y tu elemento final ha cambiado, solo en ese caso, FlashList hace una re-renderización completa de los elementos, de lo contrario no lo hará. Entonces, y si ves que nuestro color de borde depende de si 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 las data no han cambiado cuando hacemos clic en el elemento. Entonces, ¿cómo resolvemos esto? Usamos la propiedad extra data, que es parte de FlatList y FlashList, y podemos pedir a FlashList que también vuelva a renderizar si cambia el tweet actual. Bien, voy a recargar la aplicación de nuevo, y una vez que se actualice, este problema debería estar solucionado. Bien, recargar. Bien. Si miras, mi tiempo de carga se ha reducido nuevamente en casi un 50%. Empecé con 1.3 segundos, y ahora es de 238 milisegundos. Es una mejora increíble. Pero veamos si nuestro error está solucionado. Bien, sí. Puedo ver el borde azul claro de nuevo. Eso está bien. Bien. Bien, ahora sigamos adelante y ejecutemos el benchmark de nuevo y miremos nuestros nuevos números de performance al final de la tarea cinco, ¿verdad? Ahora, se ve mejor. Se ve mucho mejor. Al menos para mí lo es. Aja, 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. Bien. Eso fue todo. Antes de seguir adelante, también iré 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 todavía se desmonta. Si es así, investigaremos más a fondo. Examinaremos el código para entender por qué todavía están ocurriendo desmontajes. Al revisar 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 el número 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 de nuevo. Y verás que el contenido del tweet ya no se desmontará porque hemos pasado a FlashList. Muy bien. Para los desmontajes, estos son los elementos anteriores. Déjame deshacerme de los registros. Ahora voy a desplazarme, ¿verdad? Dios mío, todavía se está desmontando. Eso es extraño. Vale. Bien, ¿qué podría estar pasando? Vale, vamos a recargar una vez más. Quizás todavía hay algo mal. No. Muy bien, recárgalo de nuevo. Veamos. Vale, hay algunos desmontajes ocurriendo, lo cual está bien. Descubriremos por qué es así. Muy bien. Bien. Así que para sí mismo, tenemos vale. Pasemos a la tarea número seis.
Obtener tipo de elemento. ¿Qué es obtener tipo de elemento? Esta es la última pieza del rompecabezas, si lo pongo de esa manera. Si te das cuenta, los desmontajes todavía están ocurriendo porque podríamos elegir la base equivocada 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 renderizamos antes se desperdician. Veamos el code para entender por qué ocurre esto. Dentro de la celda del tweet en la línea número 34, verás una comprobación donde estoy comprobando si recommendations.length es mayor que cero, solo entonces estamos entrando en la lista flash. Así que si esta condición no coincide con la solicitud, desajuste entre elementos, podemos tener ese problema. Pero ya tenemos una lógica fija para decidir si vamos a mostrar tweets relacionados o no que es básicamente esto. Aquí es donde estamos comprobando si tweet.retweetcount es mayor que dos. Generamos algunos tweets relacionados y se los mostramos al usuario. ¿Qué pasa si le decimos a flash list que estamos haciendo algo así? Y flash list tiene una forma en la que puedes hacer eso. Muy bien, ¿cómo funciona esto? Así que este es el code que vamos a usar. Obtener tipo de elemento, puedes ir a tu elemento de Twitter de nivel superior y agregar este code. ¿Cuál es el code? Obtener tipo de elemento, vas a obtener un elemento. Y si el recuento de retweets del elemento es mayor que dos, le decimos a Flashlist que este es un elemento de tipo RT, que es la 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 averiguar internamente qué elementos debe usar para reciclar qué tipo de elementos. Y esto va a reducir el número de desmontajes que estamos viendo aún más. Aquí, déjame recargar. Mi console.log ya está descomentado, como puedes ver aquí, observaremos si todavía estamos viendo desmontajes. Sí. Muy bien. Todo está cargado, déjame desplazarme. Sí, algún desmontaje, dos desmontajes. Flash puede desmontar algunas cosas basadas en número de factores que no necesita. Pero incluso desplazándome bastante, ¿verdad? Puedes ver que no estamos obteniendo eventos de desmontaje repetidos en absoluto. Bien, te daré un minuto para hacer esto.
15. Optimizando Actualizaciones de Estado con Refs
Short description:
Los desmontajes se han ido, se puede eliminar UseEffect. Ejecute el benchmark para ver números mejorados. Discutiendo una forma alternativa de actualizar estados y evitar renders adicionales. Cree una fuente ref para rastrear el tweet fuente. Verifique si el tweet fuente es igual al tweet pasado por Flashlist. Si no es así, capture una copia en el ref y llame a set current en la misma llamada de render. Este método es más rápido que usar UseEffect.
Y dame un pulgar hacia arriba una vez que también no 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 han podido hacerlo. Pero sí, los desmontajes se han ido por completo. Eso es genial, y eso es lo que nos propusimos hacer al principio. De hecho, voy a deshacerme de 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á. Vale, veamos. Vale. Vale. Genial. Hagámoslo de nuevo. Ejecutemos el benchmark y veamos los nuevos números. Se ve mucho mejor. Estoy emocionado de ver cómo se verá el nuevo número. 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 ahora, el material está ahí, el snack está ahí, así que puedes, en el futuro, cargar el snack inicial en un dispositivo de gama baja y luego probar el final para averiguar cuánto puedes esperar mejorar. Pero sí, como en un iPhone, ya habrías alcanzado el techo ahora mismo. Así que porque el render JS no va a capturar nada más que 60 FPS por ahora. Mucha gente podría estar en 60 FPS, honestamente, en este punto, pero queda una tarea más. No ha terminado. Vale. ¿Qué, si recuerdas, en una de las tareas, añadimos un use effect. Y esto es algo que quería tocar exclusivamente, porque normalmente la gente añade use effects para actualizar sus estados y sincronizarlos con los data externos. Pero hay una forma alternativa donde puedes evitar el render extra. Nuestra configuración actual, si vuelvo al code, este use effect se va a llamar después de que hayamos hecho una actualización, y luego va a comprobar esta condición llamada set state, lo que significa que el elemento se va a renderizar dos veces. Y algunos de estos elementos tienen estas listas horizontales anidadas que son súper caras de renderizar. Así que, definitivamente no queremos hacerlo dos veces. Así que, veamos si podemos hacerlo solo una vez y cómo hacerlo. Vale. Así que, el fragmento de code está frente a ti. Déjame hacerlo y puedes seguirme. Lo que puedo hacer es, puedo crear esta fuente ref para rastrear cuál es mi tweet fuente, ¿verdad? Que viene de, digamos, Flashlist. Hice una copia de él. En lugar de use effect, ahora voy a hacer lo mismo mismo bucle de render, o camino de render. Voy a comprobar si mi tweet fuente era igual al tweet que ahora pasa Flashlist. Si no es así, capturamos una copia de él en el ref y llamamos a set current en la misma llamada de render. Lo que esto hace es, así que en este caso particular, digamos que hablo del contenido del tweet, el método de render de tweet cell, nuestro componente actual se va a llamar dos veces, pero el render del contenido del tweet se va a llamar una vez. Así que es como dos renders, pero debajo de ese árbol es solo un render. Así que Flashlist también se va a renderizar solo una vez. Así que si lo haces de esta manera, por supuesto hay múltiples formas de hacerlo, y React tiene documentado cómo funciona esto 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. De nuevo, las mejoras dependen de tu componente particular, pero como verás en este caso, va a marcar la diferencia. Sí, déjame recargar.
16. Observando la Distancia de Dibujo y los Resultados Finales
Short description:
Observemos si el error del elemento repetido todavía existe. Cambie la propiedad de distancia de dibujo en FlashList para mejorar el rendimiento. Recargue la aplicación y ejecute el benchmark final. Los resultados muestran mejoras significativas en JSFPS, especialmente en dispositivos Android. Incluso en iPhones, FlashList consume menos CPU en comparación con FlatList. La vida útil de la batería y la temperatura del dispositivo también mejoran. Echemos un vistazo rápido a los resultados. La parte de codificación de la masterclass ahora está completa. Hemos visto mejoras de rendimiento notables con FlashList. Hay una cosa más interesante para explorar: JSThread.
Y también vamos a observar si todavía vemos ese error de elemento repetido o no. De acuerdo, se ha recargado, déjame desplazarme un poco. Déjame volver. Bien, todo se ve bien. Sí. Dame un pulgar arriba si pudiste hacer esto. Genial, genial. De acuerdo, no vamos a ejecutar el benchmark todavía. 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 una más pequeña, por defecto, FlashList sólo dibuja 150 píxeles por delante mientras que FlatList dibuja 10 veces el tamaño de tu viewport por adelantado. Así que FlashList dibuja un número minúsculo de elementos en comparación con FlatList. Pero en el caso de la lista horizontal, ni siquiera necesitas 250 píxeles de dibujo por adelantado. Al menos, sabes, en este ejemplo particular, el elemento es bastante grande, así que probablemente puedo seguir adelante y cambiar también la distancia de dibujo. Voy a hacerlo cero. También puedes elegir no hacerlo, incluso sin él, veremos mucha mejora, pero hagámoslo porque sabemos que realmente no necesitamos hacerlo. Y en el caso de FlashList, ponerlo a cero no va a llevar a ningún problema funcional importante. Como en el caso de FlatList, sé que en algunos casos cuando cambias el número inicial a renderizar o el tamaño de la ventana, te encuentras con problemas. Los elementos no se cargan, pero realmente es algo sin compromiso en este caso particular. ¿Verdad? 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. Bien, sólo 200 milisegundos de tiempo de carga. De acuerdo, hagámoslo. De acuerdo, se ve bastante bien. Ni siquiera veo espacios en blanco ya. De acuerdo, vamos, vamos, vamos. 50.6, 50.6 para mí. De acuerdo, 50.6. Los resultados de Zach son bastante interesantes. Empezó con 60 FPS. Todavía en 60 FPS. Muy bien. Así que esa es la distancia de dibujo. Creo que tenemos, tenemos, y sabes que eso nos lleva al final de la parte de codificación de la masterclass. Echemos un vistazo rápido a los resultados. Así que en mi caso, si ves que empecé a 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, como por 48.9 FPS, y eso constituye como una mejora de 29 veces en JSFPS, ¿verdad? Y si miro algunos de los iPhones que vimos, ve, lo interesante a notar aquí es que incluso en el iPhone, si sólo estás viendo una mejora de 1.2X, FlashList en realidad estará consumiendo una cantidad muy pequeña de CPU en comparación con la lista plana. Así que como forzar bruscamente es posible, pero estás quemando mucha, mucha energía y batería, tu dispositivo se va a calentar, cosas así. Así que todavía verás mejoras en la batería y los dispositivos van a permanecer frescos, incluso en iOS, pero en Android, es como la noche y el día. Ya puedo ver, sabes, KB acercándose a 16 veces las mejoras antes de que los números fueran 7.2. Ahora el aumento a 116 FPS, eso es como casi 120 FPS. ¿Cuáles son los otros números grandes? De acuerdo, iPhone 11 Pro pasando de 8.8 a 60, eso es como casi seis veces de aumento. Así que en los últimos iPhones, esperamos que veas alrededor de 1.8 a 1.2 veces de mejora. Pero si observas el uso de la CPU, va a mostrar una tendencia similar a lo que estás viendo en Android. Muy bien, muy bien. Como tengo dos minutos más antes de terminar, me gustaría mostrarte una cosa más que es bastante interesante. Hasta ahora hemos estado mirando a 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 los hilos de la interfaz de usuario son comunes con FlatList. FlashList, incluso con la grabación, mantiene un alto FPS y evita la congelación de los hilos de la interfaz de usuario. 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 en realidad reduce la carga en tu UiThread aún más. Así que puedo hacer eso. Entonces, en mi dispositivo Android, voy a ir a Configuración, Opciones de desarrollador, lo siento, opción incorrecta. Hago esto todo el tiempo. Si me desplazo hacia abajo, hay algo llamado como Perfil de Hardware UiRendering en Pantalla como Barras. Bueno, volviendo a Expo. Así que primero lanzo lo que comenzamos con nuestra muestra original. Así que esto es con FlatList, tanto vertical como horizontal. Déjame recargar. Así que cada vez que ves estas barras subiendo por encima de la línea roja, eso es una caída de fotograma, y cuanto más largo es, peor es. Déjame ejecutar el benchmark y ver cómo va, vale. Muchas barras altas. Muchas barras altas, y se está pausando porque jsthread no puede mantenerse al día y no puede emitir instrucciones para dibujar. Pero tal vez al volver, va a ser mejor. Bien. 1.7 de nuevo, y ves estos enormes picos de fotogramas. Y aquí es donde tu UI también se va a congelar, no solo en blanco, en realidad se congela. Vale. Vamos a nuestra muestra de FlashList con todo hecho y arreglado. Sí, déjame recargar. Solo recargo todo el tiempo solo para estar seguro. Vale. Déjame ejecutarlo, y, vale. Bien. Incluso con la grabación, verás que nos mantenemos 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 honestamente posible, incluso en este dispositivo, si me desconecto del reflejo, hará 60 FPS. Y no tienes un solo pico enorme congelando tu hilo de UI en absoluto. Así que eso fue rápidamente algunas notas sobre el rendimiento del hilo de UI. Voy a desactivar eso rápidamente. Bien. Así que eso 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 y levanta la mano aquí si quieres hacer las preguntas aquí. No veo preguntas allí. Veo una pregunta en el Q&A aquí. Pero creo que todos- Creo que estabas codificando así que- Sí, es difícil ir a un separado, porque fue extremadamente rápido. Pero sí, adelante, levanta la mano, te desactivaremos el silencio y puedes hacer tu pregunta. O puedes escribirlo en el chat. Vale, ¿cuál era? Es la pregunta de Juan que dice, ¿pueden los elementos tener diferentes tamaños? Creo que respondimos eso en la presentación. Sí, si miras esto ya, ¿verdad? Los elementos son de diferente tamaño. ¿Verdad? Flashlist no te pregunta en ningún lugar, y este es un elemento, como este tweet y el tweet horizontal es en realidad un elemento. Porque lo estamos renderizando dentro de sí mismo. Y Flashlist no te pidió diferentes estimaciones o tamaños fijos en ningún lugar, pero aún funciona muy bien. Así que las alturas dinámicas no son un problema en absoluto. Yay. Genial, si quieres compartir tus pensamientos o comentarios, adelante, también puedes hacer eso si no tienes ninguna pregunta. Yay. Levanta el pulgar si en realidad no tienes preguntas. Vale.
Comentarios de la audiencia y ganancias de rendimiento
Short description:
Hicimos algo realmente bueno o realmente malo. Cuanto más compleja sea tu lista, más ganancias verás. En nuestro sitio web, afirmamos hasta un 10X de mejora en el rendimiento.
Hicimos algo realmente bueno o realmente malo. Quizás puedo hacer una pregunta para la audiencia, como cuántos de ustedes conocían Flashlist antes de esta masterclass o cuántos lo han probado antes de unirse a la masterclass? Quizás solo den un pulgar hacia arriba también si lo intentaron en el pasado, o ahora es la primera vez que lo ven. Genial. Bien. Veo que Zain mencionó que va a volver a React Native desde Flutter después de esta masterclass. Eso es una victoria. Sí, y gente, vean, cuanto más compleja sea tu lista, más ganancias verás. En nuestro sitio web, realmente afirmamos hasta 10X, pero puedes superar fácilmente eso si tus elementos son lo suficientemente complejos. Sí, tenemos una lista de secciones. No lo hacemos, no viene de serie, pero tenemos un tutorial en nuestra documentación sobre cómo puedes usar muy fácilmente 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. Así que esto es como un diseño al estilo Pinterest con elementos de diferentes tamaños, tal vez si tienes algunos. Puedo mostrarlo. Creo que está en mi slack. Sí, no slack. Estoy acostumbrado a decir slacks. Vale. Sí. Así es como se ve la mampostería FlashList. Tienes diferentes, los elementos pueden tener todas las alturas diferentes y aún así encajarán, y FlashList también puede organizarlos automáticamente para ti para que no obtengas columnas de alturas muy diferentes. Y es bastante rápido. Así que 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 como 120 FPS, 60, puedes maximizar tus dispositivos. Vale. Entonces, mucha gente en realidad lo ha escuchado, pero nunca lo ha probado. Espero que, ahora lo harán. Y, ya sabes, no dudes en hacérnoslo saber o contáctanos en Twitter para compartir tu experiencia. También tenemos una comunidad de Discord donde si te encuentras con problemas, puedes, está en nuestro sitio web. Puedes ir allí y hacernos preguntas, compartir tus ejemplos específicos si necesitas ayuda. Vale. Como nota final, sí, gracias a todos por unirse a nosotros. Fue, fue increíble realizar esta masterclass junto con Meric, David y Mercy. Es muy divertido para nosotros ver estos números y ver las mejoras que esta biblioteca aporta a toda la aplicación y a la comunidad en general. Realmente apreciaríamos si fueras al repositorio y nos dieras una estrella. Amamos nuestras estrellas. Y el documento también tiene todos los desarrolladores que trabajaron en esta biblioteca. Puedes seguirnos en Twitter si tienes preguntas. Y si obtuviste buenos resultados hoy, no dudes en tuitear sobre ellos y difundir la palabra porque imagino que mucha gente aún no sabe sobre esto. Así que si tuiteas y difundes la palabra, será de gran ayuda para nosotros y la comunidad. Bien, dejaré de compartir ahora, pero todavía tenemos dos minutos si alguien tiene más preguntas. Vale. Muy bien entonces. Marci, creo que podemos dejar de grabar. Genial, gente, siéntanse libres de desconectarse. Hemos terminado por hoy. Gracias por unirse a nosotros. Gracias a todos. Gracias. Nos vemos. Ciao.
Los primeros intentos de Ivan en la depuración de rendimiento fueron caóticos. Vería una interacción lenta, intentaría una optimización aleatoria, vería que no ayudaba, y seguiría intentando otras optimizaciones hasta que encontraba la correcta (o se rendía). En aquel entonces, Ivan no sabía cómo usar bien las herramientas de rendimiento. Haría una grabación en Chrome DevTools o React Profiler, la examinaría, intentaría hacer clic en cosas aleatorias, y luego la cerraría frustrado unos minutos después. Ahora, Ivan sabe exactamente dónde y qué buscar. Y en esta masterclass, Ivan te enseñará eso también. Así es como va a funcionar. Tomaremos una aplicación lenta → la depuraremos (usando herramientas como Chrome DevTools, React Profiler, y why-did-you-render) → identificaremos el cuello de botella → y luego repetiremos, varias veces más. No hablaremos de las soluciones (en el 90% de los casos, es simplemente el viejo y regular useMemo() o memo()). Pero hablaremos de todo lo que viene antes - y aprenderemos a analizar cualquier problema de rendimiento de React, paso a paso. (Nota: Esta masterclass es más adecuada para ingenieros que ya están familiarizados con cómo funcionan useMemo() y memo() - pero quieren mejorar en el uso de las herramientas de rendimiento alrededor de React. Además, estaremos cubriendo el rendimiento de la interacción, no la velocidad de carga, por lo que no escucharás una palabra sobre Lighthouse 🤐)
Con el lanzamiento de React 18 finalmente obtenemos el tan esperado renderizado concurrente. Pero, ¿cómo va a afectar eso a tu aplicación? ¿Cuáles son los beneficios del renderizado concurrente en React? ¿Qué necesitas hacer para cambiar al renderizado concurrente cuando actualices a React 18? ¿Y qué pasa si no quieres o no puedes usar el renderizado concurrente todavía?
¡Hay algunos cambios de comportamiento de los que debes estar al tanto! En esta masterclass cubriremos todos esos temas y más.
Acompáñame con tu portátil en esta masterclass interactiva. Verás lo fácil que es cambiar al renderizado concurrente en tu aplicación React. Aprenderás todo sobre el renderizado concurrente, SuspenseList, la API startTransition y más.
La adición de la API de hooks a React fue un cambio bastante importante. Antes de los hooks, la mayoría de los componentos tenían que ser basados en clases. Ahora, con los hooks, estos son a menudo componentes funcionales mucho más simples. Los hooks pueden ser realmente simples de usar. Casi engañosamente simples. Porque todavía hay muchas formas en las que puedes equivocarte con los hooks. Y a menudo resulta que hay muchas formas en las que puedes mejorar tus componentes con una mejor comprensión de cómo se puede usar cada hook de React.Aprenderás todo sobre los pros y los contras de los diversos hooks. Aprenderás cuándo usar useState() versus useReducer(). Veremos cómo usar useContext() de manera eficiente. Verás cuándo usar useLayoutEffect() y cuándo useEffect() es mejor.
ReactJS es extremadamente popular y, por lo tanto, ampliamente soportado. TypeScript está ganando popularidad y, por lo tanto, cada vez más soportado.
¿Los dos juntos? No tanto. Dado que ambos cambian rápidamente, es difícil encontrar materiales de aprendizaje precisos.
¿React+TypeScript, con los IDEs de JetBrains? Esa combinación de tres partes es el tema de esta serie. Mostraremos un poco sobre mucho. Es decir, los pasos clave para ser productivo, en el IDE, para proyectos de React utilizando TypeScript. En el camino, mostraremos el desarrollo guiado por pruebas y enfatizaremos consejos y trucos en el IDE.
En esta masterclass, aprenderás cómo construir tu primer dapp de pila completa en la blockchain de Ethereum, leyendo y escribiendo datos en la red, y conectando una aplicación de front end al contrato que has desplegado. Al final de la masterclass, entenderás cómo configurar un entorno de desarrollo de pila completa, ejecutar un nodo local e interactuar con cualquier contrato inteligente usando React, HardHat y Ethers.js.
La Biblioteca de Pruebas de React es un gran marco para las pruebas de componentes de React porque responde muchas preguntas por ti, por lo que no necesitas preocuparte por esas preguntas. Pero eso no significa que las pruebas sean fáciles. Todavía hay muchas preguntas que tienes que resolver por ti mismo: ¿Cuántas pruebas de componentes debes escribir vs pruebas de extremo a extremo o pruebas de unidad de nivel inferior? ¿Cómo puedes probar una cierta línea de código que es difícil de probar? ¿Y qué se supone que debes hacer con esa persistente advertencia de act()? En esta masterclass de tres horas, presentaremos la Biblioteca de Pruebas de React junto con un modelo mental de cómo pensar en el diseño de tus pruebas de componentes. Este modelo mental te ayudará a ver cómo probar cada bit de lógica, si debes o no simular dependencias, y ayudará a mejorar el diseño de tus componentes. Te irás con las herramientas, técnicas y principios que necesitas para implementar pruebas de componentes de bajo costo y alto valor. Tabla de contenidos- Los diferentes tipos de pruebas de aplicaciones de React, y dónde encajan las pruebas de componentes- Un modelo mental para pensar en las entradas y salidas de los componentes que pruebas- Opciones para seleccionar elementos DOM para verificar e interactuar con ellos- El valor de los mocks y por qué no deben evitarse- Los desafíos con la asincronía en las pruebas de RTL y cómo manejarlos Requisitos previos- Familiaridad con la construcción de aplicaciones con React- Experiencia básica escribiendo pruebas automatizadas con Jest u otro marco de pruebas unitarias- No necesitas ninguna experiencia con la Biblioteca de Pruebas de React- Configuración de la máquina: Node LTS, Yarn
This transcription provides a brief guide to React rendering behavior. It explains the process of rendering, comparing new and old elements, and the importance of pure rendering without side effects. It also covers topics such as batching and double rendering, optimizing rendering and using context and Redux in React. Overall, it offers valuable insights for developers looking to understand and optimize React rendering.
Remix is a web framework built on React Router that focuses on web fundamentals, accessibility, performance, and flexibility. It delivers real HTML and SEO benefits, and allows for automatic updating of meta tags and styles. It provides features like login functionality, session management, and error handling. Remix is a server-rendered framework that can enhance sites with JavaScript but doesn't require it for basic functionality. It aims to create quality HTML-driven documents and is flexible for use with different web technologies and stacks.
The Talk discusses React Forget, a compiler built at Meta that aims to optimize client-side React development. It explores the use of memoization to improve performance and the vision of Forget to automatically determine dependencies at build time. Forget is named with an F-word pun and has the potential to optimize server builds and enable dead code elimination. The team plans to make Forget open-source and is focused on ensuring its quality before release.
Today's Talk explores the use of the useEffect hook in React development, covering topics such as fetching data, handling race conditions and cleanup, and optimizing performance. It also discusses the correct use of useEffect in React 18, the distinction between Activity Effects and Action Effects, and the potential misuse of useEffect. The Talk highlights the benefits of using useQuery or SWR for data fetching, the problems with using useEffect for initializing global singletons, and the use of state machines for handling effects. The speaker also recommends exploring the beta React docs and using tools like the stately.ai editor for visualizing state machines.
Routing in React 18 brings a native app-like user experience and allows applications to transition between different environments. React Router and Next.js have different approaches to routing, with React Router using component-based routing and Next.js using file system-based routing. React server components provide the primitives to address the disadvantages of multipage applications while maintaining the same user experience. Improving navigation and routing in React involves including loading UI, pre-rendering parts of the screen, and using server components for more performant experiences. Next.js and Remix are moving towards a converging solution by combining component-based routing with file system routing.
This Talk is about interactive data visualization in React using the Plot library. Plot is a high-level library that simplifies the process of visualizing data by providing key concepts and defaults for layout decisions. It can be integrated with React using hooks like useRef and useEffect. Plot allows for customization and supports features like sorting and adding additional marks. The Talk also discusses accessibility concerns, SSR support, and compares Plot to other libraries like D3 and Vega-Lite.
Comments