miércoles, 16 de agosto de 2023

Tras la huella del Error: Cómo Solucioné un Problema de Render en React

Ayer, miércoles 16 de agosto, desde el equipo de QA me llegó un reporte de un error en uno de los desarrollos que había realizado, un error atípico y difícil de diagnosticar. Estuve en la mañana colocando Logs y debuggers por todos lados, los componentes afectados en los últimos cambios aparentemente no mostraban inconsistencias y renderizaciones fuera de lo normal. Pude replicar el error, pues sucedía al desplazarme por una serie de Tabs y el contenido correspondiente a cada Tab provocaba bloqueos en el sitio web. Usar la extensión React Devtools era imposible, pues al tener un error de bloqueo total de la pagina no era posible navegar, inspeccionar y usar extensiones de Chrome durante el crash.

Al tener un bloqueo de la pagina web es común pensar en una serie de excepciones que van rompiendo todo, también es cierto que en un contexto de desarrollo web puede tratarse de iteraciones indefinidas de un mismo elemento, componente o función, por eso, al llegar a la conclusión de que el problema debía ser un renderizado incontrolado de algún componente de React esta debía ser la sospecha #1.

Primer intento

Revisión superficial del problema y diagnostico inicial. Los nuevos cambios involucraban llamados a diferentes Queries de Grahpql y renderizado de componentes nuevos, por ello fue necesario validar los siguientes puntos:
  • Peticiones: Desde el navegador web, abrir el inspeccionador de elementos e ir hasta el Tab "Red" (o "Network" en Inglés) para validar que no existan llamados recurrentes e innecesarios de los queries de Graphql.
    • Resultado: Todo a la normalidad.
  • Errores en consola: Revisar que no se tengan errores o advertencias en la consola del navegador (Tab "Consola").
    • Resultado: Todo a la normalidad.
  • Profiling: Intentar hacer Profiling de los componentes de React usando la extension React Devtools.
    • Resultado: No se pudo realizar profiling debido al bloqueo de la pagina al momento de activar la opción cuando el bug se había presentado.
  • Error Boundary: Agregar como padre uno de los componentes custom llamado ErrorBoundary que sirve par capturar errores en los componentes hijos.
    • Resultado: No hubo errores, por lo tanto ErrorBoundary estaba puesto en vano.

Segundo intento

Lo primero que debía hacer era descartar que se trataba de un error en los componentes principales, por eso, el segundo intento para detectar el problema fue abrir el inspeccionador de elementos de Google Chrome y desde la opción de "Fuentes" (o "Sources" en Inglés) activar la casilla "Detenerse cuando se detecten excepciones". Una vez activada la detección de excepciones se procede a navegar en el sitio web para desencadenar todo tipo de excepciones sea cual sea que ocurran durante la navegación, así cuando el Bug se presente lo podremos ver en cuestión (siempre y cuando arroje una excepción).

Un par de horas después, había realizado el proceso de depuración de varios errores, encontrando y solucionando algunos problemas mínimos con la ayuda del step-by-step del inspecionador del navegador web. Este primer intento se consolida al detectar varios errores provocados por la carga Lazy Load de algunos componentes de React, sin embargo, tenia que intentar esta opción a pesar que no sirva para detectar errores de renderizado infinito en React. En conclusión, este segundo intento me sirvió para encontrar puntos de mejora y validaciones extra, pero no para hallar el problema real.

Tercer intento

Después de despejar la mente, almorzar y caminar un rato por la calle, volví a casa, hice masa de pan y la puse en un recipiente para que la levadura se activara y la masa creciera, luego abrí el sitio web de Mercado Libre (o MELI) para buscar algunos productos de intereses, y al cabo de unos minutos no había comprado nada pero si me encontraba inspeccionando el sitio web con la extension de React Devtools, encontré que algunos componentes de MELI se están renderizando de forma innecesaria con solo hacer unas pocas acciones como un hover, también vi que usan servicios Graphql y las traducciones de los productos vienen desde Backend.

En fin, durante esta inspección he terminado descubriendo de forma accidental y activando la casilla "Highlight updates when components render" ubicada en "React Developer Tools > View Settings > General > Highlight updates when components render". Activar la visualización de cambios me permitió ver cada update en los componentes de MELI, esta característica resultó ser muy útil para identificar qué componentes se están actualizando durante la navegación en el sitio web.


Una vez encontrada y activada esta característica, seguí indagando sobre el problema inicial. Durante el primer diagnostico, al intentar hacer Profiling durante la replicación del problema no se lograba iniciar y procesar debido al bloqueo de la pagina, provocando un colapso de todo el sitio web e impidiendo realizar cualquier acción, la única salida era el cierre forzado de la pestaña del navegador, sin embargo, una vez dejando activada la visualización de cambios podía navegar por el sitio web y luego replicar el problema para poder observar segundos antes del colapso qué componentes se estaban renderizando de manera descontrolada. Y así fue que logré identificar el componente a corregir.

Todo se resumió a un problema, regeneración de referencias de objetos que pasan como props a otros componentes. Los componentes recibían estos props y realizaban una acción con un useEffect, este luego realizaba otra acción que cambiaba la referencia de una de sus dependencias, y así sucesivamente hasta el final de los tiempos. Esto provocaba una cantidad de iteraciones indefinidas en el ciclo de ejecución de un componente, haciendo que a su vez los componentes hijos también sufrieran un re-renderizado. En fin, todo esto ocurrió al trabajar en la versión "16" de React, en las versiones posteriores también deben haber problemas de infinite loops en useEffects pero se deberían controlan mejor para evitar crashes en el sitio web.

Conclusiones

  • La Persistencia en la Depuración: A pesar de la complejidad y frustración inicial, aprendí la importancia de persistir en la depuración y no rendirte ante problemas difíciles de diagnosticar.
  • Enfoque Iterativo: Descubrí que abordar un problema técnico de manera iterativa, probando diferentes enfoques y herramientas, puede llevar finalmente a la identificación y resolución del problema.
  • Exploración de Herramientas de Desarrollo: Mi experiencia mostró la utilidad de aprovechar al máximo las herramientas de desarrollo disponibles, como el inspector de elementos y las extensiones como React Devtools, para analizar y entender el comportamiento de tus componentes.
  • Descubrimiento Casual: A veces, los descubrimientos más valiosos pueden surgir de manera casual. El hallazgo accidental de la opción "Highlight updates when components render" ilustra cómo explorar diversas características puede revelar soluciones inesperadas.
  • Control de Referencias y Ciclos de Vida: Aprendí sobre la importancia de controlar las referencias y las actualizaciones en los componentes de React, especialmente al trabajar con efectos en el ciclo de vida de los componentes.

viernes, 4 de agosto de 2023

Un viaje como Frontend Developer

¡Bienvenidos a mi nuevo blog! Mi blog anterior fue construido usando Gatsby y publicado desde Netlify, sin embargo, estoy buscando una forma mucho más rápida y Low Code para mantener mi blog. Por cierto, mi primer blog estaba en Médium, escribí muchos post de todo tipo, sueños, tutoriales y otras cosas personales.

Hoy quiero compartir con ustedes un poco más acerca de quién soy y cómo me he convertido en un Frontend Developer. Mi nombre es Julian, y mi pasión por la tecnología y la programación ha sido el motor que me ha impulsado en este fascinante camino.

A mediados del 2010 y 2011, desde una edad temprana, siempre me sentí atraído por el mundo de la informática. Recuerdo con cariño mis primeros días jugando con las computadoras de la escuela, tratando de entender cómo funcionaban y cómo podía interactuar con ellas. Mi curiosidad me llevó a profundizar en los conceptos básicos de programación, y pronto me encontré desarrollando mis primeros proyectos simples, pero emocionantes. Emocionantes porque mis primeros códigos fueron escritos en Bash y comúnmente escribía sentencias peligrosas para eliminar el System32, abrir cientos de ventanas de Paint hasta bloquear la computadora, y otros Scripts delicados. En varios casos estos archivos Bash venían con un icono personalizado de una carpeta con el nombre de "P0xN0", las personas que miraban esta "carpeta" con aquel supuesto contenido videográfico terminaban dando doble click y por ende dando muerte a la computadora, adiós System32.

A medida que crecía, mi fascinación por la tecnología solo aumentaba, y mi objetivo se volvía más claro: quería convertirme en un profesional de la programación y ayudar a crear aplicaciones y sitios web innovadores que impactaran la vida de las personas de manera positiva.

Mi camino hacia convertirme en Frontend Developer no fue fácil, pero cada desafío que enfrenté fue una oportunidad para aprender y mejorar mis habilidades. Estudié arduamente y me sumergí en una amplia gama de tecnologías, desde los fundamentos como HTML, CSS y JavaScript, hasta frameworks y librerías más avanzadas como React y Angular. Amo profundamente programar en TypeScript, así que todo lo que escribo suele venir bien tipado, odio usar los "any" excepto donde no hay escapatoria para no usarlo.

A lo largo de mi carrera, he enfrentado desafíos en el diseño y desarrollo de interfaces de usuario altamente interactivas, garantizando que la experiencia del usuario sea fluida y atractiva. También he tenido la oportunidad de colaborar con diseñadores, analistas y otros desarrolladores para comprender las necesidades del usuario y traducirlas en productos finales que superen sus expectativas.

La tecnología nunca deja de avanzar, y eso es lo que más me emociona de ser un Frontend Developer. Cada día hay algo nuevo que aprender, ya sea una nueva técnica de diseño, un framework emergente o una metodología de desarrollo. Mantenerme actualizado en este entorno en constante evolución es un desafío que abrazo con entusiasmo. Suelo usar Twitter, YouTube y charlas con amigos para mantenerme al día.

A través de mi trayectoria como Frontend Developer, he aprendido la importancia de la empatía y la comprensión del usuario. Al final del día, nuestro trabajo no solo se trata de escribir código, sino de resolver problemas y mejorar la vida de quienes interactúan con nuestras creaciones, por eso, todo lo que hago suele venir acompañado de buena accesibilidad Web, vivo enamorado de A11y.

Me siento bendecido de poder dedicar mi vida profesional a lo que amo, y estoy emocionado de seguir creciendo y evolucionando en este campo tan apasionante. En este blog, compartiré mis conocimientos, experiencias y consejos relacionados con el desarrollo frontend, con la esperanza de inspirar y ayudar a otros desarrolladores en su propio viaje.

Así que únanse a mí en este viaje, donde exploraremos juntos el fascinante mundo del desarrollo frontend y cómo podemos dar vida a nuestras ideas a través del código.

¡Gracias por leer! Si tienes alguna pregunta o tema que te gustaría que aborde en futuras publicaciones, no dudes en dejar un comentario. ¡Hagamos crecer esta comunidad de desarrolladores apasionados por la tecnología!

¡Nos vemos en la próxima entrada del blog!

Baking3D

  https://baking3d.mercadoshops.com.co/