2021 JavaScript Full-Stack Bootcamp är nu öppet för anmälningar!
Server Side Rendering, även kallad SSR, är förmågan hos en JavaScript-applikation att rendera på servern i stället för i webbläsaren.
Varför skulle vi vilja göra det?
- Det gör att din webbplats får en snabbare laddningstid för den första sidan, vilket är nyckeln till en bra användarupplevelse
- Det är viktigt för SEO: Sökmotorer kan (ännu?) inte indexera applikationer som uteslutande renderas på klientsidan på ett effektivt och korrekt sätt. Trots de senaste förbättringarna av indexeringen hos Google finns det andra sökmotorer också, och Google är i alla fall inte perfekt på detta område. Dessutom gynnar Google webbplatser med snabba laddningstider, och att behöva ladda klientsidan är inte bra för hastigheten
- Det är bra när folk delar en sida på din webbplats på sociala medier, eftersom de lätt kan samla in de metadata som behövs för att dela länken på ett snyggt sätt (bilder, titel, beskrivning….)
Och utan Server Side Rendering är allt din server skickar en HTML-sida utan kropp, bara några skripttaggar som sedan används av webbläsaren för att rendera applikationen.
Klientrenderade appar är bra vid all efterföljande användarinteraktion efter den första sidladdningen. Server Side Rendering gör det möjligt för oss att få den perfekta platsen mitt emellan klientrenderade appar och backend-renderade appar: sidan genereras på serversidan, men alla interaktioner med sidan när den väl har laddats hanteras på klientsidan.
Server Side Rendering har dock också sina nackdelar:
- Det är rättvist att säga att ett enkelt SSR-konceptbevis är enkelt, men komplexiteten hos SSR kan växa med komplexiteten hos din applikation
- Rendering av en stor applikation på serversidan kan vara ganska resurskrävande, och vid hög belastning kan det till och med ge en långsammare upplevelse än rendering på klientsidan, eftersom du har en enda flaskhals
Ett mycket förenklat exempel på vad som krävs för att rendera en React-app på serversidan
SSR-inställningar kan bli mycket, mycket komplexa och de flesta handledningar kommer att baka in Redux, React Router och många andra begrepp från början.
För att förstå hur SSR fungerar, låt oss börja från grunderna för att implementera ett proof of concept.
Känn dig fri att hoppa över det här stycket om du bara vill titta på biblioteken som tillhandahåller SSR och inte bry dig om grundarbetet
För att implementera grundläggande SSR kommer vi att använda Express.
Om du är nybörjare i Express, eller om du behöver lite information, kan du läsa min kostnadsfria Expresshandbok här: https://flaviocopes.com/page/ebooks/.
Varning: SSR:s komplexitet kan växa med komplexiteten i din applikation. Detta är den minimala inställningen för att rendera en grundläggande React-applikation. För mer komplexa behov kan du behöva göra lite mer arbete eller också kolla in SSR-bibliotek för React.
Jag antar att du startade en React-app med create-react-app
. Om du bara försöker kan du installera en nu med npx create-react-app ssr
.
Gå till huvudmappen för appen med terminalen och kör sedan:
npm install express
Du har en uppsättning mappar i din app-katalog. Skapa en ny mapp som heter server
, gå sedan in i den och skapa en fil som heter server.js
.
Följande create-react-app
-konventionerna bor appen i src/App.js
-filen. Vi laddar den komponenten och renderar den till en sträng med hjälp av ReactDOMServer.renderToString(), som tillhandahålls av react-dom
.
Du hämtar innehållet i ./build/index.html
-filen och ersätter <div></div>
-placeringshållaren, som är taggen där applikationen är standard, med `<div>${ReactDOMServer.renderToString(<App />)}</div>
.
Alt innehåll i build
-mappen serveras som det är, statiskt av 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, i klientprogrammet, i din src/index.js
, istället för att kalla ReactDOM.render()
:
ReactDOM.render(<App />, document.getElementById('root'))
kalla ReactDOM.hydrate()
, som är detsamma men har ytterligare möjlighet att fästa händelselister till befintlig markup när React laddas:
ReactDOM.hydrate(<App />, document.getElementById('root'))
Alla Node.js-kod måste transpileras av Babel, eftersom Node.js-kod på serversidan inte vet något om JSX eller ES Modules (som vi använder för include
-angivelserna).
Installera de här fyra paketen:
npm install @babel/register @babel/preset-env @babel/preset-react ignore-styles
ignore-styles
är ett Babel-verktyg som säger åt Babel att ignorera CSS-filer som importeras med import
-syntaxen.
Låt oss skapa en ingångspunkt i server/index.js
:
require('ignore-styles')require('@babel/register')({ ignore: , presets: })require('./server')
Bygg React-applikationen så att mappen build/ fylls på:
npm run build
och låt oss köra detta:
node server/index.js
Jag sa att det här är ett förenklat tillvägagångssätt, och det är det:
- Det hanterar inte rendering av bilder korrekt vid användning av importer, som behöver Webpack för att fungera (och som komplicerar processen mycket)
- Det hanterar inte metadata för sidhuvudet, vilket är viktigt för SEO och social delning (bland annat)
Så även om det här är ett bra exempel på hur man kan använda ReactDOMServer.renderToString()
och ReactDOM.hydrate
för att få den här grundläggande server-siderapporteringen, så räcker det inte till för användning i verkliga livet.
Server Side Rendering using libraries
SSR är svårt att göra rätt, och React har inget de-facto sätt att implementera det.
Det är fortfarande mycket diskutabelt om det är värt besväret, komplikationen och overheadkostnaden för att få fördelarna, snarare än att använda en annan teknik för att servera dessa sidor. Den här diskussionen på Reddit innehåller många åsikter i det avseendet.
När Server Side Rendering är en viktig fråga är mitt förslag att förlita sig på färdiga bibliotek och verktyg som har haft detta mål i åtanke sedan början.
I synnerhet föreslår jag Next.js och Gatsby.
Ladda ner min kostnadsfria React Handbook
The 2021 JavaScript Full-Stack Bootcamp IS NOW OPEN FOR SIGNUPS UNTIL NEXT TUESDAY! Missa inte det här tillfället, anmäl dig redan idag!
Mer React tutorials:
- VS Code setup for React development
- React Concept: Hur man returnerar flera element i JSX
- Hur man återger flera element i JSX
- React Portals
- Hur man renderar HTML i React
- Roadplanen för att lära sig React
- Ska du använda jQuery eller React?
- Hur man använder reaktkroken useRef
- React Router, hur man hämtar data från en dynamisk rutt