Cómo usar React.lazy y Suspense para componentes de carga diferida

React 16.6 llevó la división de código a un nuevo nivel. Ahora puede cargar sus componentes cuando realmente los necesite sin instalar bibliotecas adicionales.

¿Qué son la división de código y la carga diferida?

Webpack define la división de código como:

“Técnica de dividir su código en varios paquetes que luego se pueden cargar bajo demanda o en paralelo”. [Fuente]

Otra forma de decir: "cargando bajo demanda o en paralelo" es carga diferida .

Lo opuesto a la carga diferida es la carga ansiosa . Aquí todo se carga sin importar si lo usas o no.

¿Por qué usaríamos la división de código y la carga diferida?

A veces tenemos que introducir una gran cantidad de código para cubrir algunas funciones. Este código puede importar la dependencia de terceros o escribirlo por nuestra cuenta. Este código luego afecta el tamaño del paquete principal.

Descargar algunos MB es muy fácil para la velocidad de Internet actual. Todavía tenemos que pensar en los usuarios con una conexión a Internet lenta o que utilizan datos móviles.

¿Cómo se hizo antes de React 16.6?

Probablemente la biblioteca más popular para la carga diferida de componentes de React es react-loadable.

Es importante que reactjs.org aún recomiende react-loadablesi su aplicación se procesa en el servidor. [Fuente]

react-loadableen realidad es bastante similar al nuevo enfoque de React. Mostraré esto en la siguiente demostración.

¿Se necesita algo para la configuración?

Veamos qué tiene que decir reactjs.org al respecto:

"Si está usando Create React App, Next.js, Gatsby o una herramienta similar, tendrá una configuración de Webpack lista para usar para empaquetar su aplicación. Si no lo está, deberá configurar el empaquetado usted mismo . Por ejemplo, consulte las guías de instalación y de introducción en los documentos de Webpack ".

- reactjs.org

Ok, entonces se requiere Webpack , que maneja las importaciones dinámicas de los paquetes.

La siguiente demostración se genera usando Create React App.Y, en ese caso, Webpack ya está configurado y estamos listos para comenzar .

MANIFESTACIÓN

Para esta demostración, usaremos react-pdf. react-pdfes una biblioteca impresionante que se utiliza para crear archivos PDF en el navegador, el dispositivo móvil y el servidor. Podríamos generar un PDF en el servidor, pero si preferimos hacerlo en el lado del cliente, tiene un costo: el tamaño del paquete.

Estoy usando la extensión de costo de importación para Visual Studio Code para ver los tamaños de las bibliotecas utilizadas.

Digamos que nuestro requisito es generar un archivo PDF cuando un usuario hace clic en el botón.

Ahora, este es un formulario simple con un solo caso de uso. Intente imaginar una aplicación web enorme en la que esto sea una fracción de las posibilidades. Quizás esta funcionalidad no sea utilizada con mucha frecuencia por los usuarios.

Pongámonos en esa situación. La generación de PDF no se usa con mucha frecuencia y no tiene sentido cargar el código completo para cada solicitud de página.

Intentaré mostrar cómo podemos desarrollar una solución con carga diferida y sin ella.

Escaparate de carga diferida VS ansioso

Para ambos casos, usaremos un componente que importa dependencias de react-pdfun documento PDF simple y lo renderiza.

No pasa nada espectacular aquí. Importamos PDFViewer, Document, Page, Text, Viewde react-pdf. Todos estos se utilizan en el rendermétodo de PDFPreviewcomponente.

PDFPreviewRecibe solo uno propllamado title. Como su nombre lo indica, se utiliza como título en un archivo PDF recién generado.

pdfStyles.js se ve así:

Carga ansiosa

Primero veamos cómo se vería el componente principal sin carga diferida:

que muestra la siguiente vista en el navegador:

Repasemos el código juntos:

En la línea 2 importamos PDFPreviewcomponente.

En la línea 6 inicializamos el estado con valores predeterminados. namees un campo que se utiliza como título en el archivo PDF, mientras que el campo PDFPreviewes un booleano que muestra u oculta PDFPreview.

Ahora, vayamos al rendermétodo y verifiquemos qué se renderizará.

En las líneas 19 y 25 representamos una entrada y un botón. Cuando el usuario escribe en la entrada, nameel estado cambia.

Luego, cuando un usuario hace clic en "Generar PDF", showPDFPreviewse establece en true. El componente vuelve a renderizar y muestra el PDFPreviewcomponente.

Aunque PDFPreviewsolo usamos el clic del usuario, todo el código relacionado con él se incluye en el paquete de la aplicación:

Este es un entorno de desarrollo. En producción, los tamaños serían significativamente más pequeños. Aún así, no estamos dividiendo el código de manera óptima.

Carga lenta

Solo hemos realizado pequeños cambios y veámoslos.

La línea 2 se reemplaza por:

const LazyPDFDocument = React.lazy(() => import("./PDFPreview"));

Veamos qué dicen los documentos de React sobre React.lazy:

React.lazy toma una función que debe llamar a una dinámica import(). Esto debe devolver un Promiseque se resuelve en un módulo con una defaultexportación que contiene un componente React.

- reactjs.org

En la línea 27 usamos Suspense, que debe ser padre de un componente de carga diferida. Cuando showPDFPreviewse establece en verdadero, LazyPDFDocumentcomienza a cargarse.

Hasta que se resuelva el componente secundario, Suspensemuestra todo lo que se proporciona a fallbackprop.

El resultado final se ve así:

Podemos ver que 0.chunk.js pesa significativamente menos que antes y 4.chunk.js y 3.chunk.js se cargan al presionar el botón.

Conclusión

Cada vez que estamos introduciendo una nueva dependencia en nuestro proyecto, nuestra responsabilidad es evaluar su costo y comprobar cómo afecta al paquete principal.

Entonces tenemos que preguntarnos si esta funcionalidad se va a utilizar con poca frecuencia y si podemos cargarla a pedido sin sacrificar la experiencia del usuario.

Si la respuesta es sí, entonces React.Lazyy Suspenserealmente nos ayudará en esta tarea.

¡Gracias por leer! Compártelo con cualquier persona que pueda encontrarlo útil y deja comentarios.