Il 2021 JavaScript Full-Stack Bootcamp è ORA APERTO PER LE ISCRIZIONI!
Server Side Rendering, chiamato anche SSR, è la capacità di un’applicazione JavaScript di renderizzare sul server piuttosto che nel browser.
Perché mai dovremmo volerlo fare?
- permette al vostro sito di avere un tempo di caricamento della prima pagina più veloce, che è la chiave per una buona esperienza utente
- è essenziale per il SEO: i motori di ricerca non possono (ancora?) indicizzare in modo efficiente e corretto le applicazioni che rendono esclusivamente lato client. Nonostante gli ultimi miglioramenti all’indicizzazione di Google, ci sono anche altri motori di ricerca, e Google non è perfetto in ogni caso. Inoltre, Google favorisce i siti con tempi di caricamento veloci, e dover caricare lato client non è un bene per la velocità
- è fantastico quando le persone condividono una pagina del tuo sito sui social media, in quanto possono facilmente raccogliere i metadati necessari per condividere piacevolmente il link (immagini, titolo, descrizione..)
Senza Server Side Rendering, tutto ciò che il vostro server spedisce è una pagina HTML senza corpo, solo alcuni tag di script che vengono poi utilizzati dal browser per renderizzare l’applicazione.
Le applicazioni con rendering client sono ottime per qualsiasi interazione successiva dell’utente dopo il caricamento della prima pagina. Il Server Side Rendering ci permette di ottenere lo sweet spot a metà tra le app con resa client e quelle con resa backend: la pagina viene generata lato server, ma tutte le interazioni con la pagina una volta che è stata caricata sono gestite lato client.
Tuttavia anche il Server Side Rendering ha il suo svantaggio:
- è giusto dire che una semplice prova di concetto di SSR è semplice, ma la complessità di SSR può crescere con la complessità della vostra applicazione
- rendere una grande applicazione lato server può essere abbastanza dispendiosa in termini di risorse, e sotto un carico pesante potrebbe anche fornire un’esperienza più lenta del rendering lato client, dal momento che si ha un unico collo di bottiglia
Un esempio molto semplicistico di ciò che serve per renderizzare lato server un’applicazione React
Le configurazioni SSR possono diventare molto, molto complesse e la maggior parte dei tutorial incorporano Redux, React Router e molti altri concetti fin dall’inizio.
Per capire come funziona SSR, partiamo dalle basi per implementare una prova di concetto.
Sentitevi liberi di saltare questo paragrafo se volete solo esaminare le librerie che forniscono SSR e non preoccuparvi del lavoro di base
Per implementare SSR di base useremo Express.
Se sei nuovo di Express, o hai bisogno di aggiornarti, dai un’occhiata al mio Manuale Express gratuito qui: https://flaviocopes.com/page/ebooks/.
Attenzione: la complessità di SSR può crescere con la complessità della tua applicazione. Questa è la configurazione minima per rendere un’applicazione React di base. Per esigenze più complesse potrebbe essere necessario fare un po’ più di lavoro o anche controllare le librerie SSR per React.
Presumo che tu abbia iniziato un’app React con create-react-app
. Se stai solo provando, installane una ora usando npx create-react-app ssr
.
Vai alla cartella principale dell’app con il terminale, poi esegui:
npm install express
Hai una serie di cartelle nella tua directory dell’app. Crea una nuova cartella chiamata server
, poi entraci e crea un file chiamato server.js
.
Seguendo le convenzioni create-react-app
, l’app vive nel file src/App.js
. Caricheremo quel componente e lo renderizzeremo in una stringa usando ReactDOMServer.renderToString(), che è fornito da react-dom
.
Prendi il contenuto del file ./build/index.html
e sostituisci il segnaposto <div></div>
, che è il tag dove l’applicazione si aggancia per default, con `<div>${ReactDOMServer.renderToString(<App />)}</div>
.
Tutto il contenuto dentro la cartella build
sarà servito così com’è, staticamente da Express.
import path from 'path'import fs from 'fs'import express from 'express'import React from 'react'import ReactDOMServer from 'react-dom/server'import App from '../src/App'const PORT = 8080const app = express()const router = express.Router()const serverRenderer = (req, res, next) => { fs.readFile(path.resolve('./build/index.html'), 'utf8', (err, data) => { if (err) { console.error(err) return res.status(500).send('An error occurred') } return res.send( data.replace( '<div></div>', `<div>${ReactDOMServer.renderToString(<App />)}</div>` ) ) })}router.use('^/$', serverRenderer)router.use( express.static(path.resolve(__dirname, '..', 'build'), { maxAge: '30d' }))// tell the app to use the above rulesapp.use(router)// app.use(express.static('./build'))app.listen(PORT, () => { console.log(`SSR running on port ${PORT}`)})
Ora, nell’applicazione client, nel tuo src/index.js
, invece di chiamare ReactDOM.render()
:
ReactDOM.render(<App />, document.getElementById('root'))
chiamate ReactDOM.hydrate()
, che è lo stesso ma ha la capacità aggiuntiva di attaccare gli event listeners al markup esistente una volta che React viene caricato:
ReactDOM.hydrate(<App />, document.getElementById('root'))
Tutto il codice Node.js deve essere transpilato da Babel, poiché il codice Node.js lato server non sa nulla di JSX, né di ES Modules (che usiamo per le dichiarazioni include
).
Installare questi 4 pacchetti:
npm install @babel/register @babel/preset-env @babel/preset-react ignore-styles
ignore-styles
è una utility di Babel che gli dirà di ignorare i file CSS importati usando la sintassi import
.
Creiamo un punto di ingresso in server/index.js
:
require('ignore-styles')require('@babel/register')({ ignore: , presets: })require('./server')
Costruiamo l’applicazione React, in modo che la cartella build/ sia popolata:
npm run build
ed eseguiamo questo:
node server/index.js
Ho detto che questo è un approccio semplicistico, e lo è:
- non gestisce il rendering delle immagini correttamente quando si usano le importazioni, che hanno bisogno di Webpack per funzionare (e che complica molto il processo)
- non gestisce i metadati dell’intestazione della pagina, che è essenziale per scopi SEO e di condivisione sociale (tra le altre cose)
Quindi, mentre questo è un buon esempio di utilizzo di ReactDOMServer.renderToString()
e ReactDOM.hydrate
per ottenere questo rendering di base lato server, non è sufficiente per l’uso nel mondo reale.
Il rendering lato server usando le librerie
SSR è difficile da fare bene, e React non ha un modo de-facto per implementarlo.
E’ ancora molto discutibile se vale la pena il disturbo, la complicazione e l’overhead per ottenere i benefici, piuttosto che usare una tecnologia diversa per servire quelle pagine. Questa discussione su Reddit ha un sacco di opinioni al riguardo.
Quando il Server Side Rendering è una questione importante, il mio suggerimento è di affidarsi a librerie e strumenti pre-fatti che hanno avuto questo obiettivo in mente fin dall’inizio.
In particolare, suggerisco Next.js e Gatsby.
Scaricate il mio manuale gratuito di React
Il JavaScript Full-Stack Bootcamp 2021 è ora aperto per le iscrizioni fino a martedì prossimo! Non perdere questa opportunità, iscriviti OGGI!
Altri tutorial su React:
- Impostazione del codice VS per lo sviluppo di React
- Concetto di React: Immutabilità
- Come restituire elementi multipli in JSX
- Portali React
- Come rendere HTML in React
- La roadmap per imparare React
- Si deve usare jQuery o React?
- Come usare il gancio useRef React
- React Router, come ottenere dati da un percorso dinamico