Y para demostrarles lo malo que pueden ser, incluso implementé un poco de una aplicación. Así que esta es una aplicación que renderiza una lista de componentes, y tiene un poco de interactividad. Así que echen un vistazo. A la derecha, la pestaña Performance, hago clic en todas partes, y todo es instantáneo. A la izquierda, exactamente la misma aplicación, pero cometí un par de errores allí, y miren lo insoportablemente lenta que es todo esto. Solo unos pocos errores pequeños en los lugares correctos, y acabo de destruir esta aplicación. Y es solo una lista de componentes.
Entonces, los errores comunes que conducen a un rendimiento como ese, y también útiles consejos de rendimiento tips y trucos para evitar re-renderizaciones de toda la aplicación, es lo que quiero compartir con ustedes hoy. Comencemos con los errores. El primero es uno de mis favoritos, es lo que llamo el mito de useMemo y useCallback. Así como probablemente la mayoría de ustedes saben, React utiliza igualdad referencial cuando compara props o dependencias en todos los diversos hooks. Y la igualdad referencial es básicamente esto. Tenemos dos arrays o dos objetos. Si queremos compararlos, si lo hacemos así, el resultado será falso, porque estamos comparándolos por la referencia, no por el valor real.
Y desde la perspectiva de React, suena así. Tenemos un componente, renderiza un componente hijo. Paso un valor a este componente hijo que es un array. Si lo hago así, durante una re-renderización, este valor se convertirá en un valor completamente diferente. Entonces, si React compara esas props, React pensará que el valor de la prop ha cambiado. Y si escribo hooks memo y uso callback, hooks que te permiten memorizar este valor, y básicamente para preservar la referencia a este valor entre re-renderizaciones. Entonces, si extraigo este array en el hook useMemo, entonces cuando ocurre una re-renderización, React pensará que el valor en un componente hijo será exactamente el mismo. Y el hecho de que una de las razones más importantes por las que un componente se re-renderiza es un cambio de estado o prop, en combinación con cómo funcionan esos hooks, lleva a la creencia generalizada de que si memorizamos todas las props en un componente, eso evitará que este componente se re-renderice. Y esto resulta en algo que llamo un infierno de hooks useMemo o useCallback, porque memorizar absolutamente todo lleva a que tu aplicación se convierta, teniendo useMemo, envuelves en useCallback, y luego otro useCallback, es solo useMemo y useCallbacks en todas partes, y la aplicación se vuelve incomprensible y completamente ilegible y no depurable. Así que creo que estos se vuelven realmente horribles.
Pero la peor parte de todo esto es que en realidad a veces, es inútil, porque estamos olvidando un componente clave en toda esta construcción. Entonces, si echamos un vistazo, por ejemplo, a este code, vemos un componente, tiene un componente hijo y luego onClick, Prop, y queremos evitar que el componente hijo se re-renderice envolviendo onClick en un hook useCallback. Pero, ¿qué puede exactamente desencadenar que los componentes hijos se re-rendericen? Evitamos los cambios de Prop. Lo único que queda es cuando un componente padre se re-renderiza. Entonces, activaremos un estado, por ejemplo, un componente hijo se re-renderizará, y React en realidad no comprobará si Prop ha cambiado o no en esta etapa, porque la forma natural de React de tratar con los componentes es que los componentes se re-renderizan, y luego re-renderizan cada uno de los hijos. Envolver onClick aquí en useCallback es simplemente completamente inútil, no estamos haciendo nada aquí.
Comments