Procesamiento previo de rutas con reacción-snap

¿No es la renderización del servidor, pero quieres acelerar el rendimiento de tu sitio de React? Prueba la renderización previa.

react-snap es una biblioteca de terceros que renderiza previamente páginas de tu sitio en archivos HTML estáticos. Esto puede mejorar los tiempos de First Paint en tu aplicación.

A continuación, se muestra una comparación de la misma aplicación con y sin el procesamiento previo cargado en una conexión 3G y un dispositivo móvil simulados:

Una comparación de carga en paralelo La versión que usa la renderización previa se carga 4.2 segundos más rápido.

¿Por qué es útil?

El principal problema de rendimiento de las aplicaciones grandes de una sola página es que el usuario debe esperar a que los paquetes de JavaScript que componen el sitio terminen de descargarse para poder ver contenido real. Cuanto más grandes sean los paquetes, más tiempo tendrá que esperar el usuario.

Para resolver esto, 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 código HTML completo se genera en el servidor y se envía al navegador, lo que reduce los tiempos de la primera pintura, pero a costa de un tiempo hasta el primer byte más lento.

El procesamiento previo es una técnica independiente que es menos compleja que la renderización del servidor, pero que también proporciona una forma de mejorar los tiempos de la primera pintura en tu aplicación. Se utiliza un navegador sin interfaz gráfica, o uno sin interfaz de usuario, para generar archivos HTML estáticos de cada ruta durante el tiempo de compilación. Estos archivos se pueden enviar junto con los paquetes de JavaScript necesarios para la aplicación.

reaccionar-tomar

react-snap usa Puppeteer para crear archivos HTML renderizados con anterioridad 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 a tu package.json:

"scripts": {
  //...
  "postbuild": "react-snap"
}

Esto ejecutaría automáticamente el comando react-snap cada vez que se creaba una compilación nueva de las aplicaciones (npm build).

Lo último que debes hacer es cambiar la forma en que se inicia la aplicación. Cambia el archivo src/index.js por lo 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 solo usar ReactDOM.render para renderizar el elemento raíz de React directamente en el DOM, se verifica si ya hay algún nodo secundario presente para determinar si el contenido HTML se renderizó previamente (o se renderizó en el servidor). En ese caso, se usa ReactDOM.hydrate para adjuntar objetos de escucha de eventos al código HTML ya creado, en lugar de crearlo de nuevo.

Cuando se compila la aplicación, se generan archivos HTML estáticos como cargas útiles para cada ruta rastreada. Para saber 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 dentro de las Herramientas para desarrolladores de Chrome.

Comparación del antes y el después En la toma posterior, se muestra cómo se renderiza el contenido.

Destello de contenido sin estilo

Aunque el HTML estático ahora se renderiza casi de inmediato, sigue estando sin diseño de forma predeterminada, lo que puede causar el problema de mostrar un "destello de contenido sin diseño" (FOUC). Esto puede notarse especialmente si usas una biblioteca CSS en JS para generar selectores, ya que el paquete de JavaScript tendrá que terminar de ejecutarse antes de que se pueda aplicar cualquier diseño.

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 alinear directamente con el <head> del documento HTML. react-snap usa otra biblioteca de terceros de forma interna, minimalcss, a fin de extraer las CSS críticas para diferentes rutas. Para habilitar esto, especifica lo siguiente en tu archivo package.json:

"reactSnap": {
  "inlineCss": true
}

Si observas la vista previa de la respuesta en Herramientas para desarrolladores de Chrome, ahora se mostrará la página con estilo con el código CSS crítico intercalado.

Comparación del antes y el después En la toma posterior, se muestra que el contenido se renderizó y tiene un estilo debido al código CSS principal intercalado.

Conclusión

Si no usas rutas de renderización del servidor en tu aplicación, usa react-snap para renderizar previamente el código HTML estático para tus usuarios.

  1. Instálalo como una dependencia de desarrollo y comienza con la configuración predeterminada.
  2. Usa la opción experimental inlineCss para intercalar instancias críticas de CSS si funciona en tu sitio.
  3. Si usas la división de código a nivel de componente dentro de cualquier ruta, ten cuidado de no renderizar previamente un estado de carga para tus usuarios. El archivo README de react-snap abarca este tema con más detalle.