Di Rohit Kumar
Ecco cosa costruiremo in questo tutorial: una bella scheda React come questa.
In questo tutorial, useremo il rendering lato server per fornire una risposta HTML quando un utente o un crawler colpisce un URL della pagina. Gestiremo queste ultime richieste sul lato client.
Perché ne abbiamo bisogno?
Lascia che ti guidi alla risposta.
- Qual è la differenza tra il rendering lato client e quello lato server?
- Cons del rendering di React sul server
- Quando si dovrebbe usare il Server Side Rendering?
- SEO
- Migliora le prestazioni
- React Rendered on Server
- React Rendered on Client’s Browser
- Come funziona? – (4 semplici passi)
- Iniziare impostando la nostra applicazione
- Perché abbiamo bisogno di compilare i file sorgente?
- Copy Precoded & Static files
- Lato server
- src/server.js
- 2. src/template.js
- Il lato client
- src/bundle.js
- src/client.js
- Mettendo tutto insieme
- Index.js
- Build & Run
- Pronto a diventare un React Pro?
- Grazie per aver letto questo.
Qual è la differenza tra il rendering lato client e quello lato server?
Nel rendering lato client, il tuo browser scarica una pagina HTML minima. Rende il JavaScript e ci riempie il contenuto.
Il rendering lato server, d’altra parte, rende i componenti di React sul server. L’output è il contenuto HTML.
Puoi combinare questi due per creare un’app isomorfa.
Cons del rendering di React sul server
- SSR può migliorare le prestazioni se la tua applicazione è piccola. Ma può anche degradare le prestazioni se è pesante.
- Aumenta il tempo di risposta (e può essere peggio se il server è occupato).
- Aumenta la dimensione della risposta, il che significa che la pagina impiega più tempo a caricarsi.
- Aumenta la complessità dell’applicazione.
Quando si dovrebbe usare il Server Side Rendering?
Nonostante queste conseguenze del SSR, ci sono alcune situazioni in cui si può e si deve usare.
SEO
Ogni sito web vuole apparire nelle ricerche. Correggetemi se sbaglio.
Purtroppo, i crawler dei motori di ricerca non capiscono ancora JavaScript.
Questo significa che vedono una pagina bianca, non importa quanto sia utile il vostro sito.
Molte persone dicono che il crawler di Google ora interpreta JavaScript.
Per testare questo, ho distribuito l’applicazione su Heroku. Ecco cosa ho visto su Google Search Console:
Una pagina bianca.
Questo è stato il motivo principale per cui ho esplorato il rendering lato server. Specialmente quando si tratta di una pagina fondamentale come una landing page, un blog e così via.
Per verificare se Google rende il tuo sito, visita:
Search Console Dashboard > Crawl > Fetch come Google. Inserisci l’URL della pagina o lascialo vuoto per la homepage.
Seleziona FETCH AND RENDER. Una volta completato, clicca per vedere il risultato.
Migliora le prestazioni
In SSR, le prestazioni dell’applicazione dipendono dalle risorse del server e dalla velocità della rete dell’utente. Questo lo rende molto utile per i siti con molti contenuti.
Per esempio, diciamo che avete un telefono cellulare di medio prezzo con una velocità internet lenta. Provate ad accedere a un sito che scarica 4MB di dati prima di poter vedere qualcosa.
Sareste in grado di vedere qualcosa sul vostro schermo entro 2-4 secondi?
Vedereste ancora quel sito?
Non credo che lo fareste.
Un altro grande miglioramento è nel tempo di prima interazione con l’utente. Questa è la differenza di tempo da quando un utente colpisce l’URL a quando vede il contenuto.
Ecco il confronto. L’ho testato su un Mac di sviluppo.
React Rendered on Server
Il tempo di prima interazione è 300ms. Hydrate termina a 400ms. L’evento di carico esce a 500ms circa. Puoi vedere questo controllando l’immagine qui sopra.
React Rendered on Client’s Browser
Il tempo della prima interazione è 400ms. L’evento di carico esce a 470ms.
Il risultato parla da solo. C’è una differenza di 100ms nel tempo di prima interazione con l’utente per un’app così piccola.
Come funziona? – (4 semplici passi)
- Creare un Redux Store fresco ad ogni richiesta.
- Optionally dispatch alcune azioni.
- Prendere lo stato dallo Store ed eseguire SSR.
- Inviare lo stato ottenuto nel passo precedente insieme alla risposta.
Utilizzeremo lo stato passato nella risposta per creare lo stato iniziale sul lato client.
Prima di iniziare, clona/scarica l’esempio completo da Github e usalo come riferimento.
Iniziare impostando la nostra applicazione
Primo, apri il tuo editor preferito e la shell. Crea una nuova cartella per la tua applicazione. Cominciamo.
npm init --yes
Compilare i dettagli. Dopo che package.json
è stato creato, copiate le dipendenze e gli script qui sotto.
Installate tutte le dipendenze eseguendo:
npm install
È necessario configurare Babel e webpack per far funzionare il nostro script di build.
Babel trasforma ESM e react in codice comprensibile per Node e browser.
Crea un nuovo file .babelrc
e mettici la riga sottostante.
{ "presets": }
webpack raggruppa la nostra app e le sue dipendenze in un unico file. Crea un altro file webpack.config.js
con il seguente codice:
const path = require('path');module.exports = { entry: { client: './src/client.js', bundle: './src/bundle.js' }, output: { path: path.resolve(__dirname, 'assets'), filename: ".js" }, module: { rules: }}
Il processo di compilazione produce due file:
-
assets/bundle.js
– app lato client puro. -
assets/client.js
– compagno lato client per SSR.
La cartella src/
contiene il codice sorgente. I file compilati Babel vanno in views/
. La cartella views
verrà creata automaticamente se non è presente.
Perché abbiamo bisogno di compilare i file sorgente?
La ragione è la differenza di sintassi tra ESM & CommonJS. Mentre scriviamo React e Redux, usiamo pesantemente import ed export in tutti i file.
Purtroppo, non funzionano in Node. Ecco che Babel viene in soccorso. Lo script qui sotto dice a Babel di compilare tutti i file nella directory src
e di mettere il risultato in views.
"babel": "babel src -d views",
Ora, Node può eseguirli.
Copy Precoded & Static files
Se hai già clonato il repository, copia da esso. Altrimenti scarica il file ssr-static.zip da Dropbox. Estrailo e tieni queste tre cartelle all’interno della directory della tua app. Ecco cosa contengono.
- React
App
e i componenti risiedono insrc/components
. - File Redux in
src/redux/
. -
assets/ & media/
: Contiene file statici comestyle.css
e immagini.
Lato server
Crea due nuovi file chiamati server.js
e template.js
dentro la cartella src/
.
src/server.js
La magia avviene qui. Questo è il codice che stavate cercando.
import React from 'react';import { renderToString } from 'react-dom/server';import { Provider } from 'react-redux';import configureStore from './redux/configureStore';import App from './components/app';module.exports = function render(initialState) { // Model the initial state const store = configureStore(initialState); let content = renderToString(<Provider store={store} ><App /></Provider>); const preloadedState = store.getState(); return { content, preloadedState };};
Invece di fare il rendering della nostra app, dobbiamo avvolgerla in una funzione ed esportarla. La funzione accetta lo stato iniziale dell’applicazione.
Ecco come funziona.
- Passa
initialState
aconfigureStore()
.configureStore()
restituisce una nuova istanza di Store. Tienila dentro la variabilestore
. - Chiama il metodo
renderToString()
, fornendo la nostra App come input. Rende la nostra app sul server e restituisce l’HTML prodotto. Ora, la variabilecontent
memorizza l’HTML. - Prendi lo stato da Redux Store chiamando
getState()
sustore
. Tienilo in una variabilepreloadedState
. - Ritorna il
content
epreloadedState
. Li passeremo al nostro template per ottenere la pagina HTML finale.
2. src/template.js
template.js
esporta una funzione. Prende title
, state
e content
come input. Li inietta nel template e restituisce il documento HTML finale.
Per passare lo stato, il template attacca state
a window.__STATE__
all’interno di un tag <scri
pt>.
Ora puoi leggere state
sul lato client accedendo a window.__STATE__
.
Includiamo anche l’applicazione client-side SSR companion assets/client.js
in un altro tag script.
Se richiedi la versione client pura, mette solo assets/bundle.js
dentro il tag script.
Il lato client
Il lato client è abbastanza semplice.
src/bundle.js
Ecco come si scrive il wrapping di React e Redux Provider
. È la nostra pura app lato client. Nessun trucco qui.
import React from 'react';import { render } from 'react-dom';import { Provider } from 'react-redux';import configureStore from './redux/configureStore';import App from './components/app';const store = configureStore();render( <Provider store={store} > <App /> </Provider>, document.querySelector('#app'));
src/client.js
Ti sembra familiare? Sì, non c’è niente di speciale tranne window.__STATE__.
Tutto quello che dobbiamo fare è prendere lo stato iniziale da window.__STATE__
e passarlo alla nostra funzione configureStore()
come stato iniziale.
Diamo un’occhiata al nostro nuovo file client:
import React from 'react';import { hydrate } from 'react-dom';import { Provider } from 'react-redux';import configureStore from './redux/configureStore';import App from './components/app';const state = window.__STATE__;delete window.__STATE__;const store = configureStore(state);hydrate( <Provider store={store} > <App /> </Provider>, document.querySelector('#app'));
Esaminiamo i cambiamenti:
- Sostituisci
render()
conhydrate()
.hydrate()
è lo stesso dirender()
ma è usato per idratare gli elementi resi daReactDOMServer
. Assicura che il contenuto sia lo stesso sul server e sul client. - Leggete lo stato dall’oggetto finestra globale
window.__STATE__
. Memorizzalo in una variabile e cancella ilwindow.__STATE__
. - Crea un nuovo negozio con
state
come initialState.
Tutto fatto qui.
Mettendo tutto insieme
Index.js
Questo è il punto di ingresso della nostra applicazione. Gestisce le richieste e il templating.
Dichiara anche una variabile initialState
. L’ho modellata con i dati nel assets/data.json
file. Lo passeremo alla nostra funzione ssr()
.
Nota: mentre si fa riferimento a un file che è dentro src/
da un file fuori src/
, usate il normale require()
e sostituite src/
con views/
. Il motivo lo conosci (compilazione Babel).
Routing
-
/
: Per default homepage resa dal server. -
/client
: Esempio di puro rendering lato client. -
/exit
: Pulsante di arresto del server. Disponibile solo in sviluppo.
Build & Run
È ora di costruire ed eseguire la nostra applicazione. Possiamo farlo con una sola riga di codice.
npm run build && npm run start
Ora, l’applicazione è in esecuzione a http://localhost:3000.
Pronto a diventare un React Pro?
Inizio una nuova serie da lunedì prossimo per far brillare le tue abilità React, immediatamente.
Grazie per aver letto questo.
Se ti piace e lo trovi utile, seguimi su Twitter & Webflow.