¿No usas la renderización del servidor, pero aún quieres acelerar el rendimiento de tu sitio de React? Prueba la renderización previa.
react-snap
es una biblioteca de terceros que renderiza previamente las páginas de tu sitio en archivos HTML estáticos. Esto puede mejorar los tiempos de First Paint en tu aplicación.
Esta es una comparación de la misma aplicación con y sin renderización previa cargada en una conexión 3G simulada y un dispositivo móvil:
¿Por qué es útil?
El principal problema de rendimiento con las aplicaciones de una sola página grandes es que el usuario debe esperar a que se descarguen los paquetes de JavaScript que conforman el sitio para poder ver contenido real. Cuanto más grandes sean los paquetes, más tiempo deberá esperar el usuario.
Para resolver este problema, muchos desarrolladores adoptan el enfoque de renderizar la aplicación en el servidor en lugar de solo iniciarla en el navegador. Con cada transición de página o ruta, el HTML completo se genera en el servidor y se envía al navegador, lo que reduce los tiempos de primera pintura, pero a costa de un tiempo de primer byte más lento.
La renderización previa es una técnica independiente que es menos compleja que la renderización del servidor, pero también proporciona una forma de mejorar los tiempos de primera pintura en tu aplicación. Se usa un navegador sin cabeza, o un navegador sin interfaz de usuario, para generar archivos HTML estáticos de cada ruta durante el tiempo de compilación. Luego, estos archivos se pueden enviar junto con los paquetes de JavaScript necesarios para la aplicación.
react-snap
react-snap
usa Puppeteer para crear archivos HTML renderizados previamente de diferentes rutas en tu aplicación. Para comenzar, instálalo como una dependencia de desarrollo:
npm install --save-dev react-snap
Luego, agrega una secuencia de comandos postbuild
en tu package.json
:
"scripts": {
//...
"postbuild": "react-snap"
}
Esto ejecutaría automáticamente el comando react-snap
cada vez que se realice una compilación nueva de
las aplicaciones (npm build
).
Lo último que deberás hacer es cambiar la forma en que se inicia la aplicación.
Cambia el archivo src/index.js
por el siguiente:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
const rootElement = document.getElementById("root");
if (rootElement.hasChildNodes()) {
ReactDOM.hydrate(<App />, rootElement);
} else {
ReactDOM.render(<App />, rootElement);
}
En lugar de usar solo ReactDOM.render
para renderizar el elemento raíz de React directamente en el DOM, se verifica si ya hay nodos secundarios para determinar si el contenido HTML se renderizó previamente (o se renderizó en el servidor). Si ese es el caso, se usa ReactDOM.hydrate
para adjuntar objetos de escucha de eventos al HTML ya creado en lugar de crearlo de nuevo.
La compilación de la aplicación ahora generará archivos HTML estáticos como cargas útiles para cada ruta que se rastree. Para ver cómo se ve la carga útil HTML, haz clic en la URL de la solicitud HTML y, luego, en la pestaña Vistas previas en las Herramientas para desarrolladores de Chrome.
Flash de contenido sin diseño
Aunque el HTML estático ahora se renderiza casi de inmediato, sigue sin diseño de forma predeterminada, lo que puede causar el problema de mostrar un "flash de contenido sin diseño" (FOUC). Esto puede ser especialmente notable si usas una biblioteca de CSS en JS para generar selectores, ya que el paquete de JavaScript deberá terminar de ejecutarse antes de que se puedan aplicar los estilos.
Para evitar esto, el CSS crítico, o la cantidad mínima de CSS que se necesita para que se renderice la página inicial, se puede intercalar directamente en el <head>
del documento HTML. react-snap
usa otra biblioteca de terceros en segundo plano, minimalcss
, para extraer cualquier CSS crítico para diferentes rutas. Para habilitar esta función, especifica lo siguiente en el archivo package.json
:
"reactSnap": {
"inlineCss": true
}
Si observas la vista previa de la respuesta en las Herramientas para desarrolladores de Chrome, ahora se mostrará la página con diseño aplicado y el CSS crítico intercalado.
Conclusión
Si no usas rutas de renderización del servidor en tu aplicación, usa react-snap
para renderizar HTML estático de forma previa a tus usuarios.
- Instálalo como una dependencia de desarrollo y comienza con la configuración predeterminada.
- Usa la opción experimental
inlineCss
para intercalar CSS crítico si funciona para tu sitio. - Si usas la división de código a nivel de un componente dentro de cualquier ruta, ten cuidado de no renderizar previamente un estado de carga para tus usuarios. En el archivo
react-snap
README, se explica esto con más detalle.