The 2021 JavaScript Full-Stack Bootcamp is NOW OPEN FOR SIGNUPS!
Server Side Rendering, ook SSR genoemd, is het vermogen van een JavaScript-toepassing om op de server te renderen in plaats van in de browser.
Waarom zouden we dat ooit willen doen?
- het stelt uw site in staat een snellere eerste pagina laadtijd te hebben, wat de sleutel is tot een goede gebruikerservaring
- het is essentieel voor SEO: zoekmachines kunnen (nog?) niet efficiënt en correct applicaties indexeren die uitsluitend client-side renderen. Ondanks de laatste verbeteringen aan de indexering bij Google, zijn er ook andere zoekmachines, en Google is er in ieder geval niet perfect in. Ook, Google geeft de voorkeur aan sites met snelle laadtijden, en het hebben van client-side te laden is niet goed voor de snelheid
- het is geweldig als mensen delen een pagina van uw site op sociale media, zoals ze kunnen gemakkelijk verzamelen van de metadata die nodig zijn om mooi delen van de link (afbeeldingen, titel, beschrijving..)
Zonder Server Side Rendering, alles wat uw server levert is een HTML-pagina zonder body, alleen een aantal script-tags die vervolgens worden gebruikt door de browser om de applicatie te renderen.
Client-rendered apps zijn geweldig bij elke volgende interactie van de gebruiker na de eerste pagina te laden. Server Side Rendering stelt ons in staat om de sweet spot in het midden van client-rendered apps en backend-rendered apps: de pagina wordt server-side gegenereerd, maar alle interacties met de pagina zodra deze is geladen worden behandeld client-side.
Hoewel Server Side Rendering ook zijn nadeel heeft:
- Een simpel SSR proof of concept is eenvoudig, maar de complexiteit van SSR kan meegroeien met de complexiteit van uw applicatie
- Het server-side renderen van een grote applicatie kan veel resources kosten, en onder zware belasting kan het zelfs langzamer zijn dan client-side rendering, omdat je een enkele bottleneck hebt
Een zeer simplistisch voorbeeld van wat er nodig is om een React app server-side te renderen
SSR opstellingen kunnen zeer, zeer complex worden en de meeste tutorials zullen Redux, React Router en vele andere concepten vanaf het begin inbakken.
Om te begrijpen hoe SSR werkt, beginnen we bij de basis om een proof of concept te implementeren.
Voel je vrij om deze paragraaf over te slaan als je alleen wilt kijken naar de bibliotheken die SSR bieden en je niet wilt bezighouden met het grondwerk
Om basis SSR te implementeren, gaan we Express gebruiken.
Als Express nieuw voor u is, of als u een inhaalslag nodig hebt, kunt u hier mijn gratis Express-handboek lezen: https://flaviocopes.com/page/ebooks/.
Waarschuwing: de complexiteit van SSR kan meegroeien met de complexiteit van uw toepassing. Dit is de minimale setup om een basis React app te renderen. Voor meer complexe toepassingen moet je misschien wat meer werk verrichten of ook kijken naar SSR-bibliotheken voor React.
Ik neem aan dat je een React-app hebt gestart met create-react-app
. Als je het net probeert, installeer er dan nu een met npx create-react-app ssr
.
Ga met de terminal naar de hoofdmap van de app en voer uit:
npm install express
Je hebt een reeks mappen in je app-directory. Maak een nieuwe map genaamd server
, ga er dan in en maak een bestand met de naam server.js
.
Volgens de create-react-app
conventies, bevindt de app zich in het src/App.js
bestand. We gaan die component laden, en renderen naar een string met behulp van ReactDOMServer.renderToString(), die wordt geleverd door react-dom
.
Je krijgt de inhoud van het ./build/index.html
bestand, en vervangt de <div></div>
placeholder, dat is de tag waar de applicatie standaard haakt, door `<div>${ReactDOMServer.renderToString(<App />)}</div>
.
Alle inhoud in de build
map wordt geserveerd zoals het is, statisch door 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}`)})
Nu, in de client-toepassing, in uw src/index.js
, in plaats van ReactDOM.render()
aan te roepen:
ReactDOM.render(<App />, document.getElementById('root'))
roep ReactDOM.hydrate()
aan, wat hetzelfde is, maar de extra mogelijkheid heeft om event listeners aan bestaande markup te koppelen zodra React wordt geladen:
ReactDOM.hydrate(<App />, document.getElementById('root'))
Alles in de Node.js code moet worden getranspiled door Babel, omdat server-side Node.js code niets weet van JSX, noch van ES Modules (die we gebruiken voor de include
statements).
Installeer deze 4 pakketten:
npm install @babel/register @babel/preset-env @babel/preset-react ignore-styles
ignore-styles
is een hulpprogramma van Babel dat aangeeft dat het CSS-bestanden moet negeren die zijn geïmporteerd met de import
syntaxis.
Laten we een ingangspunt maken in server/index.js
:
require('ignore-styles')require('@babel/register')({ ignore: , presets: })require('./server')
Bouw de React-toepassing, zodat de map build/ is gevuld:
npm run build
en laten we dit uitvoeren:
node server/index.js
Ik zei dat dit een simplistische benadering is, en dat is het ook:
- het gaat niet correct om met het renderen van afbeeldingen bij gebruik van importen, die Webpack nodig hebben om te werken (en wat het proces een stuk ingewikkelder maakt)
- het gaat niet om metadata in de paginatitel, wat essentieel is voor SEO en social sharing doeleinden (onder andere)
Dus hoewel dit een goed voorbeeld is van het gebruik van ReactDOMServer.renderToString()
en ReactDOM.hydrate
om deze basis server-side rendering te krijgen, is het niet genoeg voor echt wereldgebruik.
Server Side Rendering met behulp van bibliotheken
SSR is moeilijk om goed te doen, en React heeft geen de-facto manier om het te implementeren.
Het is nog maar zeer de vraag of het de moeite, complicatie en overhead waard is om de voordelen te krijgen, in plaats van een andere technologie te gebruiken om die pagina’s te serveren. Deze discussie op Reddit heeft veel meningen in dat opzicht.
Wanneer Server Side Rendering een belangrijke zaak is, is mijn suggestie om te vertrouwen op vooraf gemaakte bibliotheken en gereedschappen die dit doel vanaf het begin voor ogen hebben gehad.
In het bijzonder stel ik Next.js en Gatsby voor.
Download mijn gratis React Handbook
Het 2021 JavaScript Full-Stack Bootcamp IS NU OPEN VOOR AANMELDINGEN TOT VOLGENDE TUNEDAAG! Mis deze kans niet, schrijf u TODAY in!
Meer react tutorials:
- VS Code setup voor React ontwikkeling
- React Concept: Onveranderlijkheid
- Hoe meerdere elementen terug te geven in JSX
- React Portals
- Hoe HTML te renderen in React
- Het stappenplan om React te leren
- Moet je jQuery of React gebruiken?
- Hoe gebruik je de useRef React hook
- React Router, hoe haal je data uit een dynamische route