Nunca debes enviar más código de lo necesario a tus usuarios, así que divide tus paquetes para asegurarte de que esto nunca suceda.
El método React.lazy
facilita la división de código de una aplicación de React en un
a nivel de componente con importaciones dinámicas.
import React, { lazy } from 'react';
const AvatarComponent = lazy(() => import('./AvatarComponent'));
const DetailsComponent = () => (
<div>
<AvatarComponent />
</div>
)
¿Por qué es útil?
Por lo general, una aplicación de React grande constará de muchos componentes, herramientas y bibliotecas de terceros. Si no se hace un esfuerzo para intentar cargar en diferentes partes de una aplicación solo cuando son necesarias, se puede usar un de JavaScript se enviará a tus usuarios en cuanto carguen la primera página. Esto puede afectar significativamente el rendimiento de la página.
La función React.lazy
proporciona una forma integrada de separar componentes en un
en fragmentos separados de JavaScript
con muy poco trabajo. Puedes
y, luego, controlar los estados de carga cuando la vinculas con Suspense
este componente.
Suspense
El problema con el envío de una gran carga útil de JavaScript a los usuarios es la longitud el tiempo que tardaría la página en terminar de cargarse, especialmente en dispositivos más débiles y conexiones de red. Por eso, la división de código y la carga diferida extremadamente útil.
Sin embargo, siempre habrá un ligero retraso que los usuarios deberán experimentar cuando
se recupera un componente de división de código a través de la red, por lo que es importante
mostrar un estado de carga útil. Usa React.lazy
con Suspense
ayuda a resolver este problema.
import React, { lazy, Suspense } from 'react';
const AvatarComponent = lazy(() => import('./AvatarComponent'));
const renderLoader = () => <p>Loading</p>;
const DetailsComponent = () => (
<Suspense fallback={renderLoader()}>
<AvatarComponent />
</Suspense>
)
Suspense
acepta un componente fallback
que te permite mostrar cualquier tipo de
como estado de carga. En el siguiente ejemplo, se muestra cómo funciona.
El avatar solo se renderiza cuando se hace clic en el botón, cuando se hace una solicitud
Luego, se hace para recuperar el código necesario para el AvatarComponent
suspendido.
Mientras tanto, se muestra el componente de carga de resguardo.
Aquí, el código que compone AvatarComponent
es pequeño, lo que
por qué el ícono giratorio de carga solo se muestra por un período breve Más grande
puede demorar mucho más en cargarse, especialmente en
conexiones de red débiles.
Para demostrar mejor cómo funciona, haz lo siguiente:
- Para obtener una vista previa del sitio, presiona Ver app. Luego, presiona
Pantalla completa
- Presiona `Control + Mayúsculas + J` (o `Command + Option + J` en Mac) para abrir Herramientas para desarrolladores.
- Haga clic en la pestaña Red.
- Haz clic en el menú desplegable Regulación, que está configurado en Sin limitación de forma predeterminada. Selecciona 3G rápida.
- Haz clic en el botón Click Me en la app.
El indicador de carga se mostrará por más tiempo. ¿Observas cómo todo el código que
conforma el AvatarComponent
se recupera como un fragmento separado.
![Panel de red de Herramientas para desarrolladores que muestra la descarga de un archivo thread.js](https://web.developers.google.cn/static/articles/code-splitting-suspense/image/devtools-network-panel-sh-bab60da5120ad.png?authuser=5&hl=es)
Cómo suspender varios componentes
Otra función de Suspense
es que te permite suspender varias
de la carga de los componentes, incluso si son de carga diferida.
Por ejemplo:
import React, { lazy, Suspense } from 'react';
const AvatarComponent = lazy(() => import('./AvatarComponent'));
const InfoComponent = lazy(() => import('./InfoComponent'));
const MoreInfoComponent = lazy(() => import('./MoreInfoComponent'));
const renderLoader = () => <p>Loading</p>;
const DetailsComponent = () => (
<Suspense fallback={renderLoader()}>
<AvatarComponent />
<InfoComponent />
<MoreInfoComponent />
</Suspense>
)
Esta es una forma extremadamente útil de retrasar la representación de varios componentes y, al mismo tiempo, y solo muestra un único estado de carga. Una vez que todos los componentes hayan terminado el usuario puede verlos todos al mismo tiempo.
Puedes ver esto con la siguiente incorporación:
Sin esto, es fácil encontrarte con el problema de la carga escalonada. diferentes partes de una IU que se cargan una tras otra, cada una con sus propias indicador de carga de trabajo. Esto puede hacer que la experiencia del usuario se sienta más molesta.
Soluciona errores de carga
Suspense
te permite mostrar un estado de carga temporal mientras la red
se realizan de forma interna. Pero ¿qué sucede si esas solicitudes de red fallan
por algún motivo? Es posible que no tengas conexión o que tu aplicación web esté intentando
realizar una carga diferida de una URL con versión
que esté desactualizada y ya no esté disponible tras la reimplementación del servidor.
React tiene un patrón estándar para manejar correctamente estos tipos de carga.
fallas: con un límite de error. Como se describe en la documentación,
Cualquier componente de React puede servir como límite de error si implementa uno de estos métodos (o
ambos) de los métodos de ciclo de vida static getDerivedStateFromError()
o
componentDidCatch()
Para detectar y manejar las fallas de carga diferida, puedes unir tu Suspense
.
con un componente superior que sirva como límite de error. Dentro del
método render()
del límite de error, puedes renderizar los elementos secundarios tal como están si
un error o muestra un mensaje de error personalizado si algo sale mal:
import React, { lazy, Suspense } from 'react';
const AvatarComponent = lazy(() => import('./AvatarComponent'));
const InfoComponent = lazy(() => import('./InfoComponent'));
const MoreInfoComponent = lazy(() => import('./MoreInfoComponent'));
const renderLoader = () => <p>Loading</p>;
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = {hasError: false};
}
static getDerivedStateFromError(error) {
return {hasError: true};
}
render() {
if (this.state.hasError) {
return <p>Loading failed! Please reload.</p>;
}
return this.props.children;
}
}
const DetailsComponent = () => (
<ErrorBoundary>
<Suspense fallback={renderLoader()}>
<AvatarComponent />
<InfoComponent />
<MoreInfoComponent />
</Suspense>
</ErrorBoundary>
)
Conclusión
Si no sabes por dónde comenzar a aplicar la división de código en React sigue estos pasos:
- Comienza a nivel de la ruta. Las rutas son la forma más sencilla de identificar
tu aplicación que se puede dividir. El
Documentos de reacciones
mostrar cómo se puede usar
Suspense
junto conreact-router
- Identifica los componentes grandes de una página de tu sitio que solo se renderizan en ciertas interacciones del usuario (como hacer clic en un botón). Dividiendo estas minimizará las cargas útiles de JavaScript.
- Considera dividir todo lo que esté fuera de la pantalla y no sea crítico para el usuario.