Optimiza tu aplicación react y hazla aun mas rápida

Optimiza tu aplicación react y hazla aun mas rápida

React tiene la optimización en su núcleo. Bueno, en cierto modo. Hay muchas maneras en las que React intenta asegurarse de que tu aplicación tenga una gran renderización de la interfaz de usuario sin ningún esfuerzo por tu parte. Sin embargo, las aplicaciones de tamaño medio y grande se encuentran con problemas de rendimiento una y otra vez. ¿Has pasado por eso?


Afortunadamente, hay varias formas de optimizar tu aplicación web. Por ejemplo:


  • Optimizaciones de la API
  • Agrupación de código
  • Optimización de dependencias
  • Aceleración o desembolsar
  • Fragmentos de React y convenciones de estilo
  • Memoization. En este artículo nos centraremos estrictamente en cómo lograr esto con la ayuda de ejemplos para que sea más fácil para los principiantes.

Lo primero es lo primero, ¿Qué es la memoization?


Según Wikipedia, la memoization se define de la siguiente manera:


En informática, la memoization o memorización es una técnica de optimización que se utiliza principalmente para acelerar los programas informáticos almacenando los resultados de las costosas llamadas a funciones y devolviendo el resultado almacenado en caché cuando vuelven a producirse las mismas entradas.


Es bastante sencillo, ¿verdad? Entendamos esto en términos de React.


En React, cada componente es esencialmente una función. Estas funciones generalmente toman algunos props y devuelven un hermoso HTML (olvídate de los estados por un tiempo). Digamos que los props no cambian entre renders consecutivos, ¿cambiará el HTML?


La respuesta es ¡No! Podemos utilizar el último HTML renderizado y dar un poco de descanso a nuestro procesador.


Esto se llama memoization: el proceso de almacenar en caché el resultado de una función, y devolver el valor almacenado en caché para las solicitudes posteriores.


Este concepto puede ser reutilizado para funciones genéricas también. Digamos que una función addMillionNumbers, si el millón de números no cambia, ¡no los añada de nuevo! ¡Guárdalo en la caché!


Ahora, la siguiente pregunta lógica es: ¿Cómo logramos esto con React?


1. No dejes que el props hable "mucho" - React.memo

Como ya hemos dicho, podemos evitar que un componente se vuelva a renderizar innecesariamente si los props no han cambiado. Veamos con la ayuda de tres ejemplos diferentes.


Vamos a construir una aplicación sencilla en la que pretendemos llamar a una API al pulsar un botón. ¡La API devuelve el nombre y el plato favorito de la persona dada!


Caso 1. El componente hijo no depende de ninguna prop

Para el caso #1 no utilizaremos el estado de person y más bien codificaremos los valores en el Intro.js para que podamos evitar perforar cualquier props al componente hijo.


Por el código anterior, sabemos que cualquier número de clics no afectará a lo que devuelve el componente Intro. Sin embargo, no parece ser el caso.


Al hacer clic en el botón 10 veces se vuelve a mostrar el componente Intro 10 veces, como se muestra a continuación.


Este comportamiento parece innecesario sobre todo si estamos trabajando en una aplicación grande donde esto puede causar problemas de experiencia de usuario y de rendimiento.


¿Solución? ¡React.memo! ¡Cambiemos un poco nuestro Intro.js!


Ahora, no exportamos un componente Intro sin más, sino un componente de orden superior llamado React.memo(Intro) y lo asignamos a la misma variable. memo hace es evitar que el componente se vuelva a renderizar a menos que las dependencias (props) hayan cambiado. Como podemos ver, en este caso no tenemos ningún accesorio para empezar, por lo que el componente no se vuelve a renderizar en absoluto. ¿Resultado? "Intro.js called" se imprime sólo una vez.


Caso 2. El componente hijo depende de los props

De nuevo, a partir de este código anterior, sabemos que cualquier número de clics no afectará al valor de retorno del componente Intro. Será ¡Mi nombre es Rahul y mi plato favorito es el Pollo a la Mantequilla! Sin embargo, después de hacer clic en el botón 10 veces, el componente Intro se renderiza 10 veces. Esto se debe simplemente a que cada clic desencadena un cambio de estado en Parent, que, independientemente del mismo valor, volverá a renderizarse a sí mismo y a sus componentes hijos.


¿Solución? ¡No hay puntos por adivinar! ¡React.memo!


Lo que React.memo hace esta vez es diferenciar las nuevas props del componente con sus props anteriores. Si el valor es el mismo, no lo volverá a renderizar, pero si los props cambian, digamos que en este caso el nombre cambia de Rahul a Aman, volverá a renderizar el componente Intro y no te causará ningún problema de rotura de la UI. ¿Resultado? "Intro.js called" se imprime sólo una vez en la consola.


Caso 3. El componente hijo depende de Object props

Apliquemos también aquí la misma solución. ¡React.memo!


Si ejecuta el código anterior, observará que esta vez hemos fallado. El componente de Intro se vuelve a renderizar varias veces al hacer clic en el botón. ¡React.memo ha fallado! Pero espera, ¿por qué ha ocurrido esto?


Esto ocurrió debido a algo llamado Comparación de Igualdad en JavaScript. Para describirlo muy brevemente, la referencia a person (objet) ha cambiado aunque los valores de su interior no hayan cambiado. Esto se llama comparación superficial.


Comparación superficial: Cuando se comparan objetos, no se comparan sus atributos - sólo se comparan sus referencias.


Por defecto React.memo() hace una comparación superficial de props y objetos de props. Por lo tanto, como los cambios de referencia, para React.memo el valor anterior, así como el valor actual eran diferentes, lo que dio lugar a la re-presentación. Pero también tenemos una solución para esto. Para ejecutar una comparación profunda en lugar de una superficial, podemos utilizar algo llamado areEqual.


La función areEqual(prevProps, nextProps) debe devolver true si prevProps y nextProps son iguales.


Algo así:


Esto le dirá a React que compare los valores dentro del objeto en lugar de la referencia del propio objeto, que es lo que queremos. ¿El resultado? "Intro.js called" se imprime sólo una vez en la consola.


Por cierto, si React.memo tiene un useState, useReducer o useContext en su implementación, seguirá re-renderizando cuando el estado o el contexto cambien.


2. No deje que las funciones de devolución de llamada hablen "mucho" - useCallback

Veamos otro ejemplo básico. En el siguiente código, tenemos un BigComponent , que es responsable de renderizar la pasarela de pago en nuestra aplicación. Este componente, como su nombre indica, es un componente pesado y por eso no queremos que se renderice una y otra vez.


Aquí es donde comienza el problema de rendimiento.


  • Cada vez que cualquier estado cambia dentro de la App, se fuerza una re-presentación del componente.
  • Esto a su vez recrea el paymentHandler
  • Esta recreación cambia la referencia de la función.
  • BigComponent volverá a renderizar ya que estamos pasando esta función como un prop. Curiosamente, incluso si BigComponent se memoized utilizando el anterior React.memo todavía volvería a renderizar como la referencia anterior y la referencia actual no son los mismos. ¡A pesar de que la función en sí no ha cambiado!

¿Solución? ¡UsaCallback!


useCallback es un hook de React que proporciona una versión memoizada de tus funciones callback. Esta versión memoizada del callback sólo cambiará si una de las dependencias ha cambiado. dependencyList funciona de forma similar a como lo hace en useEffect.


Ampliando el ejemplo anterior:


Como puedes ver, React.memo no ha podido evitar el re-renderizado de BigComponent.


Resultando:


Solución:


3. Descansa tu procesador - useMemo

Imaginemos que tenemos una función llamada paymentCalculator. Es una función computacionalmente cara que toma previousBalance, amountAdded y conversionRate como entradas y realiza algunos cálculos pesados para darnos la salida final. Por lo tanto, no queremos ejecutar esta función muchas veces a menos que estos 3 argumentos cambien. Esto se puede conseguir utilizando useMemo.


useMemo toma su función y un array de dependencias como entrada y memoriza el valor devuelto por la función. useMemo sólo volverá a calcular el valor memorizado cuando una de las dependencias haya cambiado. Además, si no se proporciona un array, se calculará una nueva cantidad en cada renderización. Esto es muy similar a almacenar en caché el valor y utilizarlo hasta que algo en la lista de dependencias le indique que lo reevalúe.


Conclusión

Puedes utilizar los ejemplos anteriores para probarlos de primera mano y ver el impacto por ti mismo.


¡Muchas gracias por leer!


Reactions

6

0

0

0

Access hereTo be able to comment

TheWhiteCode.com is not the creator or owner of the images shown, references are: