Esegui il pre-rendering delle route con responsive-snap

Non vuoi utilizzare 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 pre-rendering delle pagine del tuo sito in file HTML statici. In questo modo puoi migliorare i tempi di First Paint nell'applicazione.

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

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

Perché è utile?

Il principale problema delle prestazioni nelle 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 vedere contenuti reali. Più sono grandi i bundle, più a lungo l'utente dovrà attendere.

Per risolvere questo problema, molti sviluppatori adottano l'approccio del rendering dell'applicazione sul server, anziché limitarsi ad avviarla nel browser. A ogni transizione di pagina/percorso, il codice HTML completo viene generato sul server e inviato al browser, il che riduce i tempi di visualizzazione del primo byte, ma comporta un minor tempo per il raggiungimento di First Byte.

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

reazione-snap

react-snap utilizza Puppeteer per creare file HTML sottoposti a pre-rendering di diversi percorsi nella tua applicazione. Per iniziare, installala come dipendenza per lo sviluppo:

npm install --save-dev react-snap

Quindi, aggiungi uno script postbuild in package.json:

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

In questo modo il comando react-snap verrà eseguito automaticamente ogni volta che viene eseguita una nuova build delle applicazioni (npm build).

L'ultima cosa da fare è modificare la modalità di avvio dell'applicazione. Cambia 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 ReactDOM.render solo per visualizzare l'elemento React principale direttamente nel DOM, questo metodo verifica se sono già presenti nodi secondari per determinare se i contenuti HTML sono stati pre-renderizzati (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.

La creazione dell'applicazione ora genererà file HTML statici come payload per ogni route sottoposta a scansione. Puoi dare un'occhiata all'aspetto del payload HTML facendo clic sull'URL della richiesta HTML e poi sulla scheda Anteprime in Chrome DevTools.

Un confronto prima e dopo. Il post-ripresa mostra i contenuti visualizzati.

Lampo di contenuti senza stile

Sebbene il codice HTML statico venga ora visualizzato quasi immediatamente, rimane invariato per impostazione predefinita, il che potrebbe causare il problema di visualizzazione di un "lampo di contenuti senza stile" (FOUC). Questo può essere particolarmente evidente se utilizzi una libreria CSS-in-JS per generare selettori, poiché il bundle JavaScript dovrà terminare l'esecuzione prima che sia possibile applicare qualsiasi stile.

Per evitare questo problema, il codice CSS critico o la quantità minima di CSS necessaria per la visualizzazione iniziale della pagina possono essere incorporati direttamente nella sezione <head> del documento HTML. react-snap utilizza un'altra libreria di terze parti in background, minimalcss, per estrarre eventuali CSS fondamentali per route diverse. Puoi attivare questa funzionalità specificando quanto segue nel file package.json:

"reactSnap": {
  "inlineCss": true
}

Se diamo un'occhiata all'anteprima delle risposte in Chrome DevTools ora verrà visualizzata la pagina con stili, con le informazioni CSS essenziali incorporate.

Un confronto prima e dopo. La scena successiva mostra i contenuti visualizzati e con uno stile per via di CSS essenziali incorporati.

Conclusione

Se nella tua applicazione non sono presenti route di rendering lato server, utilizza react-snap per eseguire il pre-rendering del codice HTML statico ai tuoi utenti.

  1. Installala come dipendenza di sviluppo e inizia con le impostazioni predefinite.
  2. Utilizza l'opzione sperimentale inlineCss per incorporare il codice CSS fondamentale, se funziona per il tuo sito.
  3. Se utilizzi la suddivisione del codice a livello di componente in qualsiasi route, fai attenzione a non eseguire il pre-rendering dello stato di caricamento agli utenti. Il file README di react-snap tratta questo argomento in modo più dettagliato.