Es común que las SPA (aplicaciones de una sola página) dividan la funcionalidad de la aplicación en múltiples componentes independientes. La mayoría de las veces, sólo es necesario cargar y renderizar algunos componentes a la vez. Por ejemplo, si se utiliza un enrutador, solo es necesario cargar los componentes relevantes para la ruta actual. Sin embargo, de forma predeterminada, las herramientas de compilación como Vite y Webpack agrupan todo el código en un solo archivo.
Si utilizamos una herramienta de compilación adecuada, React puede permitirnos implementar la división de código separando el código del componente en múltiples archivos independientes que solo se cargan cuando es necesario.
Debería considerar la división del código si:
Es posible que la división de código no sea ideal si:
La división de código se puede lograr en React utilizando la función diferida, junto con la importación de ESModule. En Vite, por ejemplo, la importación le dice al proceso de compilación que una determinada importación se puede dividir del archivo del paquete principal.
lazy se incluye como parte del núcleo de React. Se necesita una función que debe devolver una promesa, o un objeto _"thenable" similar a una promesa. En nuestro caso, la importación devuelve una promesa. lazy solo llamará a la función e iniciará la promesa cuando sea necesario representar el componente, logrando así una carga diferida adecuada.
Esto es especialmente útil cuando se usa para cargar componentes de forma diferida en un enrutador, así que hagamos un ejemplo de eso:
import { BrowserRouter, Route, Routes } from 'react-router-dom'; import { lazy } from 'react'; // We will only load the login component's file whe needed const Login = lazy(() => import('./login')); function Router() { return ( <BrowserRouter> <Routes> <Route path='/' element={<p>Default page</p>}/> <Route path='/login' element={<Login />}/> </Routes> </BrowserRouter> ); } export default Router;
Cuando se debe renderizar un componente diferido, pasa una pequeña cantidad de tiempo mientras su archivo se carga desde el servidor. Por lo tanto, se recomienda agregar algún comportamiento de carga mientras se carga, en lugar de congelar la aplicación. Aquí es donde el componente <Suspense /> de React resulta útil.
<Suspense /> nos permite mostrar un componente alternativo mientras otro espera una promesa (entre otros usos). En nuestro caso, lo usaremos para actualizar nuestro ejemplo anterior de tal manera que se muestre un componente "cargador" mientras se carga el componente de inicio de sesión.
// ... import { lazy, Suspense } from 'react'; // ... <Routes> ... <Route path='/login' element={ // Assume that we have defined a <Loader /> component elsewhere <Suspense fallback={<Loader />}> <Login /> <Suspense/> }/> </Routes>
Al dividir su código en fragmentos más pequeños, puede reducir la cantidad de JavaScript que debe descargarse y ejecutarse cuando un usuario carga su aplicación por primera vez. Esto conduce a un tiempo de carga inicial de la página más rápido, lo que mejora la experiencia general del usuario.
Los paquetes de código más pequeños pueden dar lugar a tiempos de ejecución más rápidos, ya que el navegador puede cargar y analizar archivos más pequeños más rápidamente. Esto es particularmente beneficioso para los usuarios con conexiones de red más lentas o dispositivos menos potentes.
La división de código le permite cargar solo el código necesario para la vista o funcionalidad actual. El código innecesario se pospone hasta que realmente se necesita, lo que puede conducir a un uso más eficiente de los recursos.
Es más probable que el navegador almacene en caché los paquetes de código más pequeños. Cuando un usuario vuelve a visitar su sitio, el código almacenado en caché se puede reutilizar, lo que reduce la necesidad de volver a descargar la aplicación completa y acelera las visitas posteriores.
Tiempos de carga más rápidos y un rendimiento mejorado contribuyen a una mejor experiencia de usuario en general. Es más probable que los usuarios interactúen y regresen a una aplicación web que proporciona una interfaz fluida y receptiva.