• react
  • lazy
  • suspense

Usa React.lazy con confianza: Una forma segura de cargar componentes cuando se itera rápidamente

React.lazy es una excelente manera de cargar componentes bajo demanda y mejorar el rendimiento de tu aplicación. Sin embargo, a veces puede causar algunos problemas como "ChunkLoadError" y "Loading chunk failed".

Gao
Gao
Founder

El dilema

Hoy en día, el desarrollo de software se mueve más rápido bajo la popular filosofía de "moverse rápido y romper cosas". No es un juicio, simplemente es así. Sin embargo, este ritmo acelerado a veces puede llevar a problemas, especialmente cuando se trata de cargar componentes en React.

Si estás trabajando en un proyecto que usa React.lazy para cargar componentes bajo demanda, es posible que hayas encontrado algunos problemas como ChunkLoadError y Loading chunk failed. Aquí hay algunas posibles razones:

  • Hay un problema de red, por ejemplo, la conexión a internet del usuario es lenta o inestable.
  • El usuario está en una versión obsoleta de la aplicación, y el navegador está tratando de cargar un fragmento que ya no existe.

Usualmente, una simple actualización de la página puede resolver el problema, pero no es una gran experiencia para el usuario. Imagina si aparece una pantalla en blanco cuando el usuario navega a otra ruta - no es una buena imagen para tu aplicación.

¿Podemos equilibrar la necesidad de velocidad con la necesidad de una experiencia de usuario fluida? Claro. Déjame mostrarte cómo (con TypeScript, por supuesto).

La solución

Una solución de fuerza bruta podría ser guardar todas las versiones de los fragmentos en el servidor, evitando así el problema del "fragmento faltante". A medida que tu aplicación crece, esta solución puede volverse inviable debido al aumento de los requerimientos de espacio en disco, y aún no resuelve el problema de la red.

Dado que un reinicio o una actualización pueden resolver el problema, podemos implementar estas soluciones en nuestro código. Como el problema generalmente ocurre cuando el usuario navega a otra ruta, podemos solucionarlo incluso sin que el usuario lo note. Todo lo que necesitamos hacer es construir un contenedor alrededor de la función React.lazy que maneje los reintentos y las actualizaciones.

Ya existen algunos artículos excelentes sobre cómo implementar este tipo de solución, así que me enfocaré en la idea y el funcionamiento interno de la solución.

Crear el contenedor

El primer paso es crear un contenedor alrededor de la función React.lazy:

Manejar los reintentos

Para los problemas de red, podemos manejar los reintentos envolviendo el importFunction en una función tryImport:

Parece simple, ¿verdad? También puedes implementar el algoritmo de exponential backoff para manejar los reintentos de manera más eficiente.

Manejar las actualizaciones

Para el problema de la versión obsoleta, podemos manejar las actualizaciones atrapando el error y refrescando la página:

Sin embargo, esta implementación es muy peligrosa, ya que puede causar un bucle infinito de actualizaciones cuando el error no puede solucionarse con una actualización. Mientras tanto, el estado de la aplicación se perderá durante la actualización. Así que necesitamos la ayuda de sessionStorage para almacenar el mensaje de que hemos intentado actualizar la página:

Ahora, cuando atrapemos el error desde la función safeLazy, sabremos que es algo que no puede resolverse con una actualización.

Múltiples componentes lazy en la misma página

Todavía hay una trampa oculta en la implementación actual. Si tienes múltiples componentes lazy en la misma página, el bucle infinito de actualizaciones aún puede ocurrir porque otros componentes pueden restablecer el valor de sessionStorage. Para resolver este problema, podemos usar una clave única para cada componente:

Ahora, cada componente tendrá su propia clave en sessionStorage, y se evitará el bucle infinito de actualizaciones. Podemos seguir afinando la solución, por ejemplo:

  • Reunir todas las claves en un array, de modo que solo se necesite una clave de almacenamiento.
  • Establecer un límite de actualización para actualizar la página más de una vez antes de lanzar un error.

Pero creo que ya tienes la idea. Una solución completa en TypeScript con pruebas y configuraciones está disponible en el repositorio de GitHub. También he publicado el paquete react-safe-lazy en NPM, por lo que puedes usarlo en tu proyecto de inmediato.

Conclusión

El desarrollo de software es un trabajo delicado, y hasta los pequeños detalles pueden requerir esfuerzo para resolverse. Espero que este artículo te ayude a manejar con gracia los problemas con React.lazy y mejorar la experiencia de usuario de tu aplicación.