Solucionando Problemas de Rendimiento en React

This ad is not shown to multipass and full ticket holders
React Summit US
React Summit US 2025
November 18 - 21, 2025
New York, US & Online
The biggest React conference in the US
Learn More
In partnership with Focus Reactive
Upcoming event
React Summit US 2025
React Summit US 2025
November 18 - 21, 2025. New York, US & Online
Learn more
Bookmark
Rate this content

Next.js y otros marcos de trabajo que envuelven a React proporcionan un gran poder en la construcción de aplicaciones más grandes. Pero con gran poder viene una gran responsabilidad de rendimiento - y si no prestas atención, es fácil añadir varios segundos de penalización de carga en todas tus páginas. ¡Vaya! Vamos a recorrer un estudio de caso de cómo unas pocas horas de depuración de rendimiento mejoraron tanto los tiempos de carga como los de análisis para la aplicación Centered en varios cientos por ciento cada uno. Aprenderemos no solo por qué ocurren esos problemas de rendimiento, sino cómo diagnosticarlos y solucionarlos. ¡Viva el rendimiento! ⚡️

This talk has been presented at React Advanced 2023, check out the latest edition of this React Conference.

FAQ

Power Fixing React Performance Woos es una serie donde Josh Goldberg guía a través de mejoras de rendimiento en aplicaciones web, utilizando ejemplos prácticos como el sitio web center.app.

La velocidad es crucial para retener usuarios, mejorar las conversiones y proporcionar una experiencia de usuario positiva, especialmente en dispositivos con hardware limitado o baja conectividad.

Josh Goldberg recomienda la implementación de carga diferida, optimización de iframes, y el uso de modernos frameworks como NextJS que configuran automáticamente un buen rendimiento.

Un iframe permite embeber otra página HTML dentro de una página. Muchos iframes en una sola página pueden ralentizar significativamente la carga y el rendimiento debido a que cada iframe se carga como una página independiente.

La carga diferida implica cargar solo los elementos necesarios inicialmente y cargar el resto conforme se necesitan, como mostró Josh con el ejemplo de limitar el número de iframes cargados inicialmente en center.app.

Josh utilizó el Analizador de Paquetes de Webpack integrado con Next.js para identificar y eliminar archivos grandes e innecesarios, mejorando así el rendimiento de la aplicación.

El tree shaking es una técnica de optimización que elimina código no utilizado de los archivos finales de una aplicación, lo que ayuda a reducir el tamaño del paquete y mejorar los tiempos de carga.

Las exportaciones de barril pueden conducir a la inclusión de código no utilizado si no se manejan correctamente. Optimizarlas mediante importaciones directas de componentes necesarios puede reducir el tamaño del paquete y mejorar el rendimiento.

Knip es una herramienta que ayuda a identificar y eliminar código no utilizado en proyectos, promoviendo un código más limpio y eficiente que mejora el tiempo de compilación y el rendimiento de la aplicación.

Josh Goldberg
Josh Goldberg
22 min
23 Oct, 2023

Comments

Sign in or register to post your comment.
Video Summary and Transcription
Esta charla discute varias estrategias para mejorar el rendimiento de React, incluyendo la carga perezosa de iframes, analizando y optimizando paquetes, arreglando las exportaciones de barril y el tree shaking, eliminando código muerto, y almacenando en caché cálculos costosos. El orador comparte su experiencia en la identificación y solución de problemas de rendimiento en una aplicación del mundo real. También destacan la importancia de auditar regularmente webpack y los analizadores de paquetes, utilizando herramientas como Knip para encontrar código no utilizado, y contribuyendo con mejoras a las bibliotecas de código abierto.

1. Introducción al Rendimiento de React

Short description:

Hola, y bienvenidos a Power Fixing React Performance Woos. El rendimiento web es increíble. Los marcos modernos como SvelteKit, Nuxt, Next, Remix y Nastro son buenas opciones para el rendimiento. Voy a guiarte a través de una serie de cinco mejoras que hice en el popular sitio web center.app. La primera mejora es abordar los 81 incrustaciones de iframe.

Hola, y bienvenidos a Power Fixing React Performance Woos, conmigo, Josh Goldberg. Soy un mantenedor de código abierto. Trabajo en el ecosistema de TypeScript y escribí un libro, Aprendiendo TypeScript, publicado por O'Reilly, pero no estamos aquí para hablar de todo eso.

Estamos aquí para hablar sobre el rendimiento web, sobre cómo solucionar cosas. El rendimiento web es increíble. Si no estás convencido, te recomiendo encarecidamente web.dev. ¿Por qué importa la velocidad? Resumiendo sus puntos, la velocidad es importante para retener a tus usuarios, es más probable que se queden. Mejorar las conversiones, eso es bueno para el dinero. No es bueno para tu experiencia de usuario porque a la gente no le gustan las páginas web lentas, hecho divertido. Es un punto de accesibilidad porque las personas con hardware limitado y/o ancho de banda a menudo no pueden usar o tienen problemas para usar páginas web realmente pesadas y lentas. No lo queremos.

Los frameworks modernos como SvelteKit, Nuxt, Next, Remix y Nastro y todos estos hacen muchas buenas elecciones por ti. Así que si estás usando algo como, digamos, NextJS, que veremos más tarde, a menudo está configurado para hacer del buen rendimiento la opción predeterminada, lo que en realidad hace más difícil escribir páginas web lentas. Pero no es imposible. No te impiden introducir agresiones de rendimiento. Incluso si estás haciendo todo bien, todavía es posible que con el tiempo se vayan colando cosas. Voy a guiarte a través de una serie de cinco mejoras que hice, solo algunas de las cuales tocan realmente el código de React en el popular sitio web center.app.

Ahora, esto es de un equipo perfectamente bueno y respetable. No hicieron nada mal, excepto que simplemente no tuvieron tiempo para centrarse en el rendimiento, lo que significó que algunos problemas de rendimiento se colaron en la aplicación, con los que pude ayudar. Normalmente, cuando abordo un problema de rendimiento, es en cuatro fases. Identificación, ver qué está mal, idealmente con algo que pueda medir. Investigación, buscar cuál es la causa raíz. Implementación, idealmente de una solución. Y confirmación de que la solución realmente solucionó lo que queríamos.

La primera de estas es una muy rápida, 81 incrustaciones de iframe. He visto esto muy raramente, así que fue realmente genial encontrarlo aquí. Cuando miras la página de center.apps slash quotes, antes de las correcciones, tardaría una eternidad. Mira lo lenta que era. Y la causa raíz era, veremos pronto, que tenía muchos iframes. Pero el efecto, el síntoma, era que tardaba una eternidad y se sentía lenta.

2. Identificando el Problema con los Iframes

Short description:

Y tenía una pista porque había visto muchos tweets aparecer en una página y tardar un rato antes. Así que simplemente mirando a través de las herramientas de desarrollo, vemos una grabación aquí de mí confirmando que, sí, es lo que sospechaba que hay muchos iframes en esta página. Y hecho divertido sobre los iframes. Podemos ver aquí que hay bastantes de ellos.

Y tenía una pista porque había visto muchos tweets aparecer en una página y tardar un rato antes. Así que simplemente mirando a través de las herramientas de desarrollo, vemos una grabación aquí de mí confirmando que, sí, es lo que sospechaba que hay muchos iframes en esta página. Y hecho divertido sobre los iframes. Podemos ver aquí que hay bastantes de ellos. Cada iframe es como una página dentro de una página. Así que cuando tienes 84 de ellos o 81 de ellos, eso es bastante páginas. Cuando se tomó esta grabación ayer, en realidad había más iframes de los que había inicialmente hecho la investigación. Fue un total de 94. Así que eso es bastante la desaceleración. Y todos aparecen al mismo tiempo, lo que significa que todos se están cargando al mismo tiempo, por lo que la página se congeló y tardó un rato en cargar. Boom.

3. Solucionando la Representación de Iframes con Carga Diferida

Short description:

Al implementar una solución para la representación de múltiples iframes, se utilizó la carga diferida. Inicialmente solo se representa un subconjunto de los iframes, y se cargan más a medida que el usuario interactúa con la página. La carga diferida mejoró el rendimiento al reducir el tiempo de carga inicial. Este enfoque no es específico de React y se puede aplicar a otros proyectos de desarrollo web. Es importante optimizar las aplicaciones para el rendimiento, incluso si inicialmente estaban bien elaboradas. La carga diferida es una estrategia recomendada para la representación de grandes cantidades de contenido, especialmente cuando solo una parte de este es inicialmente visible para los usuarios.

Al implementar una solución, primero encontré donde se representan los iframes, que es este componente de tarjetas de uso general. Aquí está simplificado, pero en esencia, carga los datos de la tarjeta usando un hook, y luego para cada pieza de esos data, almacenada en un array, se mapearía en este componente de tarjeta, representándolo como un componente hijo. Y ese componente de tarjeta llama a React Twitter Embed, que es un paquete NPM popular perfectamente bueno que incrusta un tweet como un iframe.

Esa es la forma estándar de usar las características de incrustación de tweets externos de Twitter, especialmente desde que se volvieron solo privados o solo de costo para sus APIs. Entonces, grandes números, docenas, casi 100 iframes todos representándose a la vez. La estrategia que a menudo tomaría en una situación como esta es la carga diferida. Esta es una simplificación de la solución que implementamos con carga diferida. Primero, hacemos un dot-slice a las tarjetas, de modo que solo la tarjeta 0 hasta, en este caso comenzando en 6, se representan a la vez. Luego, cada vez que se carga una tarjeta, al cargar, incrementamos o agregamos un poco a un contador extra, diciendo que podemos cargar adicionalmente esta cantidad de tarjetas. Entonces, después de que se cargan las primeras tarjetas, podemos seguir cargando más y más.

Ahora, 6 es un número arbitrario, pero funcionó bien aquí porque ese es aproximadamente el número máximo de iframes que alguien vería al cargar la página por primera vez. En teoría podríamos haberlo basado en el viewport de la página o algo así, pero no tuve tiempo, solo estaba haciendo esto por diversión. Y, solo para confirmar, mucho más rápido para grabar. Todavía está cargando la misma cantidad de iframes, solo está esperando para cargar. Está siendo perezoso al cargar todos menos los primeros 6. Entonces, yay, eso se sintió bien. Y como veremos en las cuatro investigaciones restantes, no hay mucho material específico de React aquí. Pero, son buenos principios web generales. Entonces, algunas conclusiones. Uno, las aplicaciones no optimizadas son, en mi experiencia, las más divertidas de investigar porque podrían estar totalmente bien elaboradas, simplemente no han tenido tiempo de hacer esas frutas bajas, esas victorias mucho más sencillas para el performance. Dos, este código probablemente estaba totalmente bien cuando se escribió por primera vez. Imagino que cuando se implementó la página por primera vez probablemente solo tenía 6 o 12 citas como máximo, no es ideal pero no está en ninguna parte cerca de casi 100 iframes. Y por último, la carga diferida es increíble, muy recomendada como estrategia. Si tienes un montón de cosas que quieres mostrar y solo algunas de ellas son inicialmente visibles para los usuarios, tal vez esperes para representar el resto de ellas hasta un segundo o dos. Sigamos adelante.

Imágenes incrustadas ocultas. Esto fue divertido. Entonces, hice una puntuación de performance, que es la estándar de DevTools, hey, ¿cómo está el performance? dentro de la familia general de verificaciones de Lighthouse para una página. Y vino con una puntuación de 36, que no es ideal, está en rojo. Y bajando las oportunidades sugeridas para crecer, que recomendaría encarecidamente investigar si alguna vez obtienes una puntuación de performance en rojo o amarillo, la que primero me llamó la atención fue, tamaño total 26 mil y medio kib, o aproximadamente dos docenas de megabytes.

4. Analizando los Paquetes e Identificando el Problema

Short description:

Vaya, eso es mucho código cargado por la página. Utilicé el Analizador de Paquetes de Webpack para analizar los paquetes y fragmentos de JavaScript en la aplicación. Esto me ayudó a identificar el problema con el archivo illustration.js de las características de Gcal, que era la mayor parte de cualquier fragmento por un orden de magnitud. Contenía imágenes codificadas en base64 y código no utilizado.

Vaya, eso es mucho código, eso es mucha información enviada a través de la red. ¿Por qué se estaba cargando tanta información? ¿Por qué la página estaba cargando tanta información? Bueno, abrí esta gran herramienta llamada el Analizador de Paquetes de Webpack. Como la Aplicación Centralizada está escrita en Next.js, pudimos usar la muy sencilla integración de Next.js con el Analizador de Paquetes, lo que hizo relativamente sencillo abrir el require Next slash Bundle Analyzer y ejecutarlo si el proceso y analizar es verdadero. En otras palabras, seguí las instrucciones y luego ejecuté este comando, MPM run build. Esto creó una versión de producción local de la aplicación analizando los paquetes o los fragmentos generados de JavaScript.

5. Analizando el Problema con las Características de Gcal

Short description:

Y mi parte favorita de la herramienta es que viene con una bonita visualización. illustration.js de las características de Gcal era lo más grande en la página, convirtiendo el fragmento de la aplicación en una monstruosidad de nueve megabytes. El archivo contenía imágenes codificadas en base64, lo cual no es ideal para el rendimiento. Eliminé el archivo, lo que resultó en un fragmento de página mucho mejorado y una disminución en la Pintura de Contenido más Grande de 17.6 segundos a 13.2 segundos.

Y mi parte favorita de la herramienta es que viene con una bonita visualización. Y esta visualización mostró que illustration.js de las características de Gcal era, con diferencia, lo más grande en la página, la parte más grande de cualquier fragmento por un orden de magnitud, varios megabytes. Convirtió el fragmento más grande y más importante, el fragmento de la aplicación, en una monstruosidad de nueve megabytes. Enorme. Nunca había visto algo tan grande en algo revisado en el repositorio. Me encanta.

Esto me parece realmente genial. Así que miré el archivo y vi que tenía un montón de imágenes incrustadas como base64. Ahora, base64 es una forma de codificar una imagen o algún trozo de data como una cadena. Y es totalmente razonable usarlo para imágenes pequeñas. Pero si tienes una que codifica a millones de caracteres, si es una imagen de varios megabytes, codificarla en base64 en tus SVGs dentro de tus componentes de React generalmente no es una buena idea para el performance. Podría haber sido una forma rápida y agradable de prototipar una característica. Pero esto no es bueno para la producción porque requiere que el usuario descargue y cargue megabytes tras megabytes de JavaScript con esta codificación base64 para ejecutar tu página. No es bueno.

Además, este código no se utilizaba. En ninguna parte de la aplicación se renderizaba realmente la ilustración de las características de GCL. Así que simplemente eliminé el archivo. Sin problemas. Al volver a ejecutar el npm run build con analyze true, vimos un fragmento de página mucho mejorado. Ahora hablaré de más mejoras sobre esto más adelante. Pero por ahora estaba bastante satisfecho con esto. Bajar de 11 a menos de 7.5, es una mejora bastante buena en el tamaño total. Yay. Y sólo para confirmar, volví a ejecutar las herramientas de desarrollo de Lighthouse y vi que, bueno, la Pintura de Contenido más Grande mejoró de 17.6 segundos, más o menos en unas pocas ejecuciones, a 13.2. Pero curiosamente, la puntuación general de performance en realidad no mejoró. Y creo que esto se debe a que la puntuación general de performance es un factor de problemas incluyendo LCP, y LCP sólo puede pesar hasta cierto punto. Así que más allá de cierto punto, LCP es tan malo como puede ser. Más adelante, veremos que mejora, lo prometo. Pero sí, todavía cuatro segundos y medio, más o menos, mejoraron la Pintura de Contenido más Grande o cuánto tiempo tarda en pintar la cosa visual más grande en las páginas, creo que es una buena mejora para el usuario. Así que agridulce.

6. Conclusiones de la Investigación de Rendimiento

Short description:

Mis conclusiones aquí fueron: uno, todavía es realmente divertido investigar el rendimiento de aplicaciones no optimizadas. Dos, audita regularmente tus analizadores de webpack y de paquetes. Tres, algunas métricas pueden requerir múltiples correcciones antes de mejorar. LCP mejoró, pero la puntuación general de rendimiento no lo hizo y eso está bien.

Mis conclusiones aquí, fueron: uno, todavía es realmente divertido investigar el performance de aplicaciones no optimizadas. Encontrar fragmentos extraños y extravagantes como este. Dos, similar a cómo podrías querer ejecutar regularmente todas las páginas de tu sitio para ver si están funcionando bien, incluso si son lentas, audita regularmente tus, tus analizadores de webpack, tu analizador de paquetes, quizás ver si hay algún fragmento o paquete humorísticamente grande en algún lugar de allí. Y tres, algunas métricas requerirán múltiples correcciones antes de que se produzca una mejora. LCP mejoró, pero la puntuación general de performance no lo hizo y eso está bien. Mientras se produzca un beneficio para el usuario, estoy contento.

7. Problema con las Exportaciones de Barril y el Tree Shaking

Short description:

Tres archivos index.js gigantes son un síntoma de las exportaciones de barril y de no estar haciendo tree shaking. Las exportaciones de barril son un patrón común en JavaScript donde un archivo de índice exporta múltiples archivos. La teoría detrás del tree shaking es que elimina el código no utilizado de las dependencias antes de la compilación. Sin embargo, en este caso, las partes no utilizadas del barril no se eliminaron.

Pero bien, echemos otro vistazo a esa salida del analizador de paquetes. Tres, gigantes archivos index.js. ¿Qué está pasando ahí? Ahora, esto es un síntoma de las exportaciones de barril y de no estar haciendo tree shaking, dos términos que deberíamos explicar. La exportación de barril es un patrón común en JavaScript cuando algún archivo, como un archivo de índice, exporta un montón de otros archivos. Es conveniente para que quien quiera importar esas otras cosas, pueda tomarlas de un solo lugar, ese único barril. Y en teoría, el tree shaking, que es el proceso de eliminar el código no utilizado de tus dependencias antes de que entren en la compilación, debería eliminar las partes del barril que no se utilizan. En este caso, parece que no lo están.

8. Mejorando el rendimiento del paquete y la regla ESLint

Short description:

Y solo para confirmar, solo se encontraron 34 importaciones para el paquete FortAwesome/ProLiteSVGIcons. Importar directamente desde los archivos individuales en lugar de la exportación de barril mejoró dramáticamente el paquete. El problema no estaba con Next.js o las importaciones/exportaciones de barril, sino con las herramientas de la época. Se escribió una regla ESLint para prevenir el uso accidental de las exportaciones de barril. El rendimiento mejoró con Contentful Paint LCP, tiempo total de bloqueo e índice de velocidad. El rendimiento ahora está en el área promedio.

Y solo para confirmar esto, realicé una búsqueda, ¿cuántas veces se importa este paquete FortAwesome/ProLiteSVGIcons? Solo 34 veces. Ahora, en realidad he usado este paquete antes. Es realmente agradable. Es una colección rápida y bien construida de iconos SVG de diferentes pesos. Y todos están bastante afinados para el rendimiento. Ninguno de ellos es enorme. Por lo que solo 34 importaciones de él kind of raised my alarm bells de algo raro, algo sospechoso está sucediendo aquí. 34 es un número bastante bajo.

Entonces, probé algo. Intenté, en lugar de importar desde la exportación de barril, porque he visto exportaciones de barril que no se han sacudido antes. Intenté importar directamente desde los archivos que contienen los activos. En lugar de importar, digamos, tanto los iconos de ábaco como de bebé desde la raíz, el barril, los importé desde sus archivos individuales. ¡Y voilà! Aplicar esa solución en las 34 importaciones de iconos SVG ligeros mejoró dramáticamente el paquete. Redujo mi número de gigantes barriles index.js de tres a dos. Lo que significaba que esa prueba de concepto mostrando qué pasaría si ya no usaba la exportación de barril fue, de hecho, una mejora significativa para la aplicación! Ahora, debo señalar aquí, Next.js 13.1, que se lanzó después de que hice esta investigación, mejoró bastante la detección de importaciones de barril para el tree shaking. Y creo que más tarde, las versiones posteriores de Next.js hicieron más trabajo para mejorar la situación. Así que el problema aquí ya no es Next.js. El problema ciertamente no son las importaciones de barril o las exportaciones de barril. El problema es simplemente que las herramientas de la época no soportaban este caso de uso y desde entonces se ha parcheado. Pero de todos modos, escribí una regla ESLint porque es una buena idea escribir reglas ESLint o piezas generales de automatización que eviten que las personas hagan cosas que no quieres que hagan en el futuro. Aunque había arreglado todas estas importaciones ahora, queríamos asegurarnos de que alguien no introdujera accidentalmente un nuevo uso de las exportaciones de barril. Esta regla ESLint dice que para cualquier declaración de importación con un valor de fuente que provenga de fordawesome cualquier cosa como iconos S3G sin nada después de él obtendría un informe de contexto diciéndote que uses la ruta individual. Puedes ver en la entrada de mi blog que enlazaré más tarde que también escribí un fixer para arreglar automáticamente cualquier importación lo cual fue realmente útil para aplicar automáticamente en toda la base de código.

Volviendo a ejecutar el rendimiento. Sí, finalmente vimos una mejora de 36 a 51. Mejoramos el Contentful Paint LCP de 13 a 12 más o menos. También mejoramos significativamente el tiempo total de bloqueo lo que me hace pensar que el análisis de scripts fue un problema aquí y mejoramos el índice de velocidad. Así que estoy bastante contento con esto. Por fin el rendimiento ya no estaba en rojo. Al menos estaba en amarillo, lo que llaman área promedio.

9. Mejorando el rendimiento y eliminando el código muerto

Short description:

13.2 fue bastante, bastante lento. Así que me alegra que lo hayamos mejorado. Algunas conclusiones: 1. Asegúrate de que tu herramienta soporte el tree shaking y las exportaciones/importaciones de barril. 2. Prueba de concepto de correcciones más grandes antes de invertir demasiado tiempo. 3. Automatiza las buenas prácticas para ahorrar tiempo y evitar la aplicación manual. El código no utilizado es perjudicial para la legibilidad y los tiempos de construcción. Una herramienta increíble llamada Knip ayuda a identificar y eliminar el código muerto.

13.2 fue bastante, bastante lento. Así que me alegra que lo hayamos mejorado. Algunas conclusiones. Uno, asegúrate de que tu tree shaking grandes dependencias, de nuevo las exportaciones de barril, las importaciones de barril, totalmente bien. Es un patrón muy válido en muchos casos. Solo asegúrate de que tu tooling los soporte bien. Dos, es una buena idea si vas a hacer una corrección más grande como escribir una regla personalizada de ESLint para probar el concepto. Asegúrate de que no estás gastando demasiado tiempo haciendo algo que no te dará mucho beneficio. Y tres, ama la automation. Siempre que puedas hacer cumplir automáticamente una buena práctica, hazlo de esa manera para que no tengas que hacer cumplir manualmente o limpiar errores o malos usos de ella más tarde.

Genial. Hablando de código no utilizado, esto no fue tanto una investigación de performance como una buena práctica general. Digamos que tienes una función que nunca se llama. Sería bueno tener una herramienta que te diga que este es código muerto. Deberías borrarlo. O digamos un tipo, una interfaz, que tal vez antes estaba asociada con una función pero ya no se usa. O tal vez incluso tienes una dependencia que solía ser utilizada tal vez y ya no lo es. Sería bueno tener algo que te diga que esto está muerto. Por favor, elimínalo. Y el código no utilizado es malo. Quiero que me digan que está muerto porque el código no utilizado tiene dos grandes inconvenientes. Por un lado, hace que tus archivos fuente sean menos legibles. Hay más cosas que analizar cuando estás tratando de entender. Y dos, a menudo causa compilaciones más largas. Al menos, las dependencias que no se utilizan ocupan tiempo en tus instalaciones tu npmci o equivalentes. Y si estás haciendo algún tipo de linting y/o construyendo etc. en tu código fuente, toman tiempo para ser linted, construido y así sucesivamente. Y todo eso se suma para causar que el desarrollo sea más lento para hacer que tu dev se ralentice, lo cual es malo porque quieres que tus devs trabajen lo más rápido y eficientemente posible. Afortunadamente, hay esta increíble herramienta. Mira esta ridícula vaca que hicieron llamada Knip.

10. Uso de Knip para encontrar código no utilizado

Short description:

Knip es una herramienta que encuentra código no utilizado en tu proyecto. Se puede instalar como una dependencia de desarrollo y ejecutar con configuraciones predeterminadas. Hay configuraciones disponibles para analizar archivos específicos. Aunque puede que no encuentre mucho en cada proyecto, sigue siendo beneficioso para la habilitación del desarrollador y la prevención de problemas futuros. Asegúrate de que tus desarrolladores estén contentos y considera agregar herramientas útiles. Las soluciones preventivas conocidas son valiosas, y Knip puede descubrir cantidades significativas de código no utilizado. Recuerda, '¡Knip antes de enviarlo!'

Knip hace lo que quiero. Encuentra código no utilizado. Así que sin entrar demasiado en ventas sobre ello, puedes instalarlo como una dependencia de desarrollo opcionalmente y luego puedes simplemente ejecutar npx knip y ejecutará algunas configuraciones predeterminadas y encontrará código no utilizado para ti. Ahora, cada proyecto es diferente, así que puedes configurarlo. Tiene algunas configuraciones agradables. Por ejemplo, esta toma en cuenta el archivo index de tu proyecto como el punto de entrada y luego también analiza todos los archivos de tu proyecto que son source anything.ts. Pero lo ejecutamos y realmente no encontramos mucho, pero lo comprobamos como un paso de CI porque no todas las soluciones de performance siguen directamente las investigaciones con conclusiones y puntuaciones de Lighthouse. A veces simplemente estás ejecutando la habilitación del desarrollador que es un buen objetivo por sí mismo. Quieres que tus desarrolladores sean geniales y el trabajo futuro evitado sigue siendo bueno y trabajo evitado. Así que algunas conclusiones aquí, uno, asegúrate de que tus desarrolladores estén contentos. Si hay tooling que quieres agregar que sería útil, ve si puedes encontrar tiempo para hacerlo. Dos, las soluciones preventivas conocidas definitivamente valen la pena. He visto a Kinect encontrar megabytes tras megabytes y otras bases de código. Así que sabía que Knip probablemente eventualmente encontraría este problema si no añadíamos Knip. Y tres, como dice el readme de Knip, Knip antes de enviarlo, me encanta. Pero bien, volvamos a las investigaciones.

11. Investigando el rendimiento con Emojis

Short description:

Mi favorito de todos ellos porque implica emojis y código abierto, este fue divertido. Todavía tarda unos segundos en ejecutarse, lo cual es un poco inusual. Un segundo completo, un poco más, se gasta en el plugin de emojis para Draft.js, el editor de texto. To Short parece estar haciendo algunas expresiones regulares bastante sofisticadas. NS.toShort tardó casi 700 milisegundos. Crear una expresión regular enorme tiende a ser lento. Terminamos creando un caché, donde si se estaba haciendo una gran cantidad de trabajo, lo almacenamos en una variable para que el trabajo solo necesite hacerse la primera vez que se llama a la función. La pausa se resolvió en su mayoría, y subimos de 51 a 65, casi 15 puntos en total mejor. La pintura más grande cayó de 12 a siete. El tiempo total de bloqueo se volvió verde. El índice de velocidad mejoró. Enviamos esta mejora de caché a la dependencia Upstream, la biblioteca de código abierto.

Mi favorito de todos ellos porque implica emojis y código abierto, este fue divertido. Echa un vistazo a esta grabación. En las herramientas de desarrollo y la pestaña performance recargamos, rastreamos y medimos. Vemos que incluso después de que la página ha cargado el título, lo que significa que los scripts se han cargado, todavía tarda unos segundos en ejecutarse, lo cual es un poco inusual incluso para los servidores de desarrollo local.

Y si miramos el perfil que se procesó podemos ver que hay, mientras la página está ejecutando sus scripts, un par de segundos de blanco total antes de llegar a la página de inicio. Y si nos acercamos allí y solo miramos, vemos que hay una tarea larga, eso es esa rayas rojas que indican que está pasando demasiado. Y dentro de eso, un segundo completo, un poco más, se gasta en el plugin de emojis para Draft.js, el editor de texto. Y gran parte de eso se gasta repetidamente en esta función NS.toShort.

¿Qué está pasando aquí? To Short parece estar haciendo algunas expresiones regulares bastante sofisticadas. Ahora en las herramientas de desarrollo, si haces clic en donde el nombre de la función se da un enlace azul, ¡aha! Te llevan a donde está esa función en el código fuente en tus herramientas de desarrollo, y mira esto, está anotado que NS.toShort tardó casi 700 milisegundos. Ese es el tiempo que se pasa dentro de esa función. 700 milisegundos solo en esta función. Eso es un cuello de botella de performance si alguna vez he visto uno.

Entonces, ¿qué está pasando aquí? Ahora en realidad tuve un tiempo realmente divertido investigando esto con otra persona de código abierto, un chico muy agradable llamado Marvin H. Ha estado escribiendo una gran serie de publicaciones de blog llamada Acelerando la Web. Los he enlazado más adelante, lo recomendaría encarecidamente. Marvin y yo nos metimos en una llamada de Zoom y miramos este NS.toShort. Aquí hay una simplificación de su implementación. En esencia, toma una cadena y ejecuta un utilitario replaceAll en la cadena con una enorme expresión regular que contiene todo tipo de emojis. Ahora, crear una enorme expresión regular tiende a ser lento si la estás creando dinámicamente basándote en muchas cosas, lo cual estaba haciendo esta función. De nuevo, estoy simplificando demasiado la investigación, lee la publicación del blog si quieres más, pero lo que terminamos haciendo en uno o dos lugares fue crear un caché, donde si se estaba haciendo una gran cantidad de trabajo, digamos, creando una enorme expresión regular, lo almacenamos en una variable para que el trabajo solo necesite hacerse la primera vez que se llama a la función. Ooh, genial. Me hizo feliz. Y solo confirmando al volver a ejecutar performance, la pausa se resolvió en su mayoría, y vaya, mira eso. Subimos de 51 a 65, casi 15 puntos en total mejor. La pintura más grande cayó de 12 a siete. El tiempo total de bloqueo se volvió verde. El índice de velocidad mejoró. Este fue un cambio feliz para mí. Así que en realidad enviamos esto como una mejora, este caché a la dependencia Upstream, la biblioteca de código abierto.

12. Conclusión y puntos clave

Short description:

Se fusionó unos meses después. Mientras tanto, utilicé el paquete npm-patch para aplicarlo localmente para poder obtener los cambios antes de que surgieran en el repositorio Upstream. Rendimiento bueno. Encontramos iframes y utilizamos la carga perezosa. Eliminamos archivos no utilizados y solucionamos el tree shaking con una regla de ESLint. Knip evitó el código no utilizado. Almacenamos en caché el resultado de un cálculo costoso. Recursos disponibles en línea. Muchas gracias a todos. Saludos.

Se fusionó unos meses después. Mientras tanto, utilicé el paquete npm-patch para aplicarlo localmente para poder obtener los cambios antes de que surgieran en el repositorio Upstream. Marvin y yo estábamos muy contentos con esto.

Y eso es todo lo que quería mostrar con las investigaciones de rendimiento. Hay mucho más en lo que podríamos profundizar. Podríamos profundizar en el perfilado de React, hay un gran conjunto de herramientas de desarrollo. Podríamos entrar en los bucles y hooks de React y todas estas cosas. Pero esta masterclass es remota y para la mitad del tiempo que llevaría entrar en esos temas. Así que repasemos las cosas en las que pudimos profundizar.

Performance bueno. Hay muchas razones por las que los usuarios deberían preocuparse y tú deberías preocuparte por el performance. Miramos bastantes investigaciones diferentes. Encontramos muchos iframes donde la carga perezosa fue la solución. Encontramos imágenes incrustadas ocultas yendo a las herramientas de desarrollo para encontrar donde los grandes bloques eran visibles y luego simplemente eliminando los archivos no utilizados. Vimos que el tree shaking no funcionaba para las exportaciones de barril que se solucionó con una regla de ESLint, más tarde una versión actualizada de Next.js. Vimos que el código no utilizado se evitaba en el futuro con Knip y vimos mi favorito, los emojis donde almacenamos en caché el resultado de un cálculo costoso.

Todos estos recursos están disponibles en línea. El post del blog web dev Why Speed Matters es genial. Cada una de estas cinco investigaciones tiene su propio post en mi blog y el blog de Marvin incluye acelerando el JavaScript ecosystem, parte seis. Las partes del uno al cinco también son bastante entretenidas así como nuestras siete en adelante. Eso es todo lo que tengo para ustedes. Muchas gracias a todos. Saludos. ♪♪♪

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

Una Guía del Comportamiento de Renderizado de React
React Advanced 2022React Advanced 2022
25 min
Una Guía del Comportamiento de Renderizado de React
Top Content
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.
Construyendo Mejores Sitios Web con Remix
React Summit Remote Edition 2021React Summit Remote Edition 2021
33 min
Construyendo Mejores Sitios Web con Remix
Top Content
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.
Compilador React Forget - Entendiendo React Idiomático
React Advanced 2023React Advanced 2023
33 min
Compilador React Forget - Entendiendo React Idiomático
Top Content
Joe Savona
Mofei Zhang
2 authors
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.
Uso efectivo de useEffect
React Advanced 2022React Advanced 2022
30 min
Uso efectivo de useEffect
Top Content
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.
Acelerando tu aplicación React con menos JavaScript
React Summit 2023React Summit 2023
32 min
Acelerando tu aplicación React con menos JavaScript
Top Content
Mishko, the creator of Angular and AngularJS, discusses the challenges of website performance and JavaScript hydration. He explains the differences between client-side and server-side rendering and introduces Quik as a solution for efficient component hydration. Mishko demonstrates examples of state management and intercommunication using Quik. He highlights the performance benefits of using Quik with React and emphasizes the importance of reducing JavaScript size for better performance. Finally, he mentions the use of QUIC in both MPA and SPA applications for improved startup performance.
Enrutamiento en React 18 y más allá
React Summit 2022React Summit 2022
20 min
Enrutamiento en React 18 y más allá
Top Content
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.

Workshops on related topic

Masterclass de Depuración de Rendimiento de React
React Summit 2023React Summit 2023
170 min
Masterclass de Depuración de Rendimiento de React
Top Content
Featured Workshop
Ivan Akulov
Ivan Akulov
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 🤐)
Next.js para Desarrolladores de React.js
React Day Berlin 2023React Day Berlin 2023
157 min
Next.js para Desarrolladores de React.js
Top Content
Featured WorkshopFree
Adrian Hajdin
Adrian Hajdin
En esta avanzada masterclass de Next.js, profundizaremos en conceptos clave y técnicas que permiten a los desarrolladores de React.js aprovechar al máximo Next.js. Exploraremos temas avanzados y prácticas prácticas, equipándote con las habilidades necesarias para construir aplicaciones web de alto rendimiento y tomar decisiones arquitectónicas informadas.
Al final de esta masterclass, serás capaz de:1. Comprender los beneficios de los Componentes del Servidor React y su papel en la construcción de aplicaciones React interactivas, renderizadas por el servidor.2. Diferenciar entre el tiempo de ejecución de Edge y Node.js en Next.js y saber cuándo usar cada uno en función de los requisitos de tu proyecto.3. Explorar técnicas avanzadas de Renderizado del Lado del Servidor (SSR), incluyendo streaming, fetching paralelo vs. secuencial, y sincronización de datos.4. Implementar estrategias de caché para mejorar el rendimiento y reducir la carga del servidor en las aplicaciones Next.js.5. Utilizar Acciones React para manejar la mutación compleja del servidor.6. Optimizar tus aplicaciones Next.js para SEO, compartir en redes sociales, y rendimiento general para mejorar la descubrabilidad y la participación del usuario.
Aventuras de Renderizado Concurrente en React 18
React Advanced 2021React Advanced 2021
132 min
Aventuras de Renderizado Concurrente en React 18
Top Content
Featured Workshop
Maurice de Beijer
Maurice de Beijer
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.
Consejos sobre React Hooks que solo los profesionales conocen
React Summit Remote Edition 2021React Summit Remote Edition 2021
177 min
Consejos sobre React Hooks que solo los profesionales conocen
Top Content
Featured Workshop
Maurice de Beijer
Maurice de Beijer
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.
Presentando FlashList: Construyamos juntos una lista performante en React Native
React Advanced 2022React Advanced 2022
81 min
Presentando FlashList: Construyamos juntos una lista performante en React Native
Top Content
Featured Workshop
David Cortés Fulla
Marek Fořt
Talha Naqvi
3 authors
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
React, TypeScript y TDD
React Advanced 2021React Advanced 2021
174 min
React, TypeScript y TDD
Top Content
Featured Workshop
Paul Everitt
Paul Everitt
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.