Esegui il pre-rendering delle route con responsive-snap

Non hai il rendering lato server, ma vuoi comunque velocizzare le prestazioni del tuo sito React? Prova il pre-rendering.

react-snap è una libreria di terze parti che esegue il prerendering delle pagine del tuo sito in file HTML statici. In questo modo puoi migliorare i tempi di prima colorazione nell'applicazione.

Ecco un confronto della stessa applicazione con e senza prerendering caricato su una connessione 3G simulata e su un dispositivo mobile:

Un confronto del caricamento affiancato. La versione che utilizza il pre-rendering viene caricata più velocemente di 4,2 secondi.

Perché è utile?

Il problema di prestazioni principale delle applicazioni di grandi dimensioni a pagina singola è che l'utente deve attendere il completamento del download dei bundle JavaScript che compongono il sito prima di poter visualizzare i contenuti reali. Più grandi sono i bundle, più a lungo l'utente dovrà attendere.

Per risolvere questo problema, molti sviluppatori adottano l'approccio di eseguire il rendering dell'applicazione sul server invece di avviarla solo sul browser. A ogni transizione di pagina/percorso, il codice HTML completo viene generato sul server e inviato al browser. Questo riduce i tempi di First Paint, ma ha un costo inferiore.

Il pre-rendering è una tecnica separata e meno complessa del rendering server, ma consente anche di migliorare i tempi di First Paint nella tua applicazione. Viene utilizzato un browser headless o senza interfaccia utente per generare file HTML statici di ogni route durante il tempo di creazione. Questi file possono quindi essere spediti insieme ai bundle JavaScript necessari per l'applicazione.

reazione-snaps

react-snap utilizza Puppeteer per creare file HTML prerenderizzati di diverse route nella tua applicazione. Per iniziare, installala come dipendenza di sviluppo:

npm install --save-dev react-snap

Quindi aggiungi uno script postbuild in package.json:

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

Il comando react-snap veniva eseguito automaticamente ogni volta che viene creata una nuova build delle applicazioni (npm build).

L'ultima cosa da fare è modificare la modalità di avvio dell'applicazione. Modifica il file src/index.js come segue:

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);
}

Anziché utilizzare solo ReactDOM.render per eseguire il rendering dell'elemento React principale direttamente nel DOM, questo controlla se sono già presenti nodi figlio per determinare se i contenuti HTML sono stati sottoposti a pre-rendering (o visualizzati sul server). In questo caso, viene utilizzato ReactDOM.hydrate per collegare gli ascoltatori di eventi al codice HTML già creato, anziché crearne uno nuovo.

Con la creazione dell'applicazione, ora verranno generati file HTML statici come payload per ogni route sottoposta a scansione. Per verificare l'aspetto del payload HTML, fai clic sull'URL della richiesta HTML e quindi sulla scheda Anteprime in Chrome DevTools.

Un confronto prima e dopo. La ripresa successiva mostra il rendering dei contenuti.

Flash di contenuti senza stile

Anche se ora l'HTML statico viene visualizzato quasi immediatamente, rimane ancora senza stile per impostazione predefinita e ciò potrebbe causare il problema della visualizzazione di un "lampo di contenuti senza stile" (FOUC). Ciò può essere notato in particolare se utilizzi una libreria CSS-in-JS per generare selettori, poiché il bundle JavaScript dovrà terminare l'esecuzione prima di poter applicare qualsiasi stile.

Per evitare questo problema, il CSS critico o la quantità minima di CSS necessaria per la visualizzazione della pagina iniziale può essere incorporato direttamente nel <head> del documento HTML. react-snap utilizza un'altra libreria di terze parti dietro le quinte, minimalcss, per estrarre eventuali CSS critici per diverse route. Puoi attivare questa funzionalità specificando quanto segue nel file package.json:

"reactSnap": {
  "inlineCss": true
}

Se diamo un'occhiata all'anteprima della risposta in Chrome DevTools, ora viene visualizzata la pagina con stili applicati con CSS essenziali integrati.

Un confronto prima e dopo. La sequenza successiva mostra i contenuti visualizzati e gli stili vengono definiti grazie a CSS essenziali incorporati.

Conclusione

Se la tua applicazione non ti presenta route di rendering lato server, usa react-snap per eseguire il pre-rendering dell'HTML statico per i tuoi utenti.

  1. Installalo come dipendenza per lo sviluppo e inizia con solo le impostazioni predefinite.
  2. Utilizza l'opzione sperimentale inlineCss per incorporare codice CSS fondamentale se funziona per il tuo sito.
  3. Se utilizzi la suddivisione del codice a livello di componente all'interno di qualsiasi route, fai attenzione a non eseguire il prerendering di uno stato di caricamento agli utenti. Il file README DI react-snap illustra questo aspetto in modo più dettagliato.