Estoy usando React v17 y React Router v6+. Cuando cargo la página, el navegador descarga todo el js, que tiene alrededor de 900 kb, lo que reduce el tiempo de carga inicial.
Mis rutas se definen así
const PrivateRoute = lazy(() => import("../utils/AuthenticatedRoutes")); const Profile = lazy(() => import("../modules/Settings/User/Profile")); const Buddies = lazy(() => import("../modules/Buddies/Buddies")); const Buddy = lazy(() => import("../modules/Buddies/Buddy")); const App = () => { return ( <Suspense fallback={<Loader />}> <Routes> <Route path="/" element={<Landing />} /> <Route path="/profile" element={<PrivateRoute render={<Profile />} />} /> <Route path="/buddies" element={<PrivateRoute render={<Buddy />} />} /> </Routes> </Suspense> ) }
Este es el componente Ruta privada
const PrivateRoute = ({ render }: { render: any }) => { const location = useLocation(); const { loggedIn } = useSelector((state: RootState) => state.userReducer); const pathname = location.pathname; if (!loggedIn) { return <Navigate to={`/login?redirectTo=${pathname}&search=${location.search}`} />; } return render; };
Problema: cuando cargo cualquier página en la aplicación, incluso la que no tiene ningún elemento, se descarga todo el JS de 999kb y no creo que la carga diferida deba funcionar de esa manera.
¿Cómo puedo manejar esto?
No veo ningún problema manifiesto con la forma en que implementó su código. La división del código parece estar funcionando.
Sugiero refactorizar el componente PrivateRoute
para que sea un componente de ruta de diseño en lugar de un componente contenedor.
Ejemplo:
import { Navigate, Outlet, useLocation } from 'react-router-dom'; const PrivateRoute = () => { const location = useLocation(); const { loggedIn } = useSelector((state: RootState) => state.userReducer); const pathname = location.pathname; if (!loggedIn) { return <Navigate to={`/login?redirectTo=${pathname}&search=${location.search}`} />; } return <Outlet />; };
...
const PrivateRoute = lazy(() => import("../utils/AuthenticatedRoutes")); const Profile = lazy(() => import("../modules/Settings/User/Profile")); const Buddies = lazy(() => import("../modules/Buddies/Buddies")); const Buddy = lazy(() => import("../modules/Buddies/Buddy")); const App = () => { return ( <Suspense fallback={<Loader />}> <Routes> <Route path="/" element={<Landing />} /> <Route element={<PrivateRoute />}> <Route path="/profile" element={<Profile />} /> <Route path="/buddies" element={<Buddy />} /> </Route> </Routes> </Suspense> ) }
Con esta implementación, veo el componente Loader
"blip" en la pantalla momentáneamente por primera vez al que se enruta cada componente importado dinámicamente.
Creo que podría ser, como dijo Colin en un comentario, que los componentes importados dinámicamente simplemente no son una parte significativa del tamaño total del paquete de aplicaciones.
Esto es normal. Está envolviendo toda la aplicación con Suspenso, que se resuelve directamente con su respaldo mientras que todo lo que está debajo está suspendido.
Suspense
con el react router
? Debe definir Suspense
para cada ruta que desee tener carga diferida. Entonces, cuando se llama a la ruta, el suspenso llamará al respaldo mientras se suspende cualquier cosa debajo de ella.
const PrivateRoute = lazy(() => import("../utils/AuthenticatedRoutes")); const Profile = lazy(() => import("../modules/Settings/User/Profile")); const Buddies = lazy(() => import("../modules/Buddies/Buddies")); const Buddy = lazy(() => import("../modules/Buddies/Buddy")); const App = () => { return ( <Routes> <Route path="/" element={<Landing />} /> <Route path="/profile" element={<PrivateRoute render={<React.Suspense fallback={<Loader />}><Profile /></React.Suspense>} />} /> <Route path="/buddies" element={<PrivateRoute render={<React.Suspense fallback={<Loader />}><Buddy /></React.Suspense>} />} /> </Routes> ) }
Esto es lo mismo que la documentación oficial.