A 2021-es JavaScript Full-Stack Bootcamp már nyitva áll a jelentkezők előtt!
A szerver oldali renderelés, más néven SSR, egy JavaScript alkalmazás azon képessége, hogy a böngésző helyett a szerveren rendereljen.
Miért is szeretnénk ezt?
- ez lehetővé teszi a webhely gyorsabb első oldal betöltési idejét, ami a jó felhasználói élmény kulcsa
- a SEO szempontjából elengedhetetlen: a keresőmotorok (még?) nem tudják hatékonyan és helyesen indexelni a kizárólag kliensoldalon renderelő alkalmazásokat. A Google legutóbbi indexelési fejlesztései ellenére vannak más keresőmotorok is, és a Google semmiképpen sem tökéletes ebben. Emellett a Google a gyors betöltési idejű oldalakat részesíti előnyben, és a kliensoldali betöltés nem tesz jót a sebességnek
- nagyszerű, amikor az emberek megosztják az oldalad egy oldalát a közösségi médiában, mivel könnyen össze tudják gyűjteni a link szép megosztásához szükséges metaadatokat (képek, cím, leírás…)
Kiszolgálóoldali renderelés nélkül a kiszolgálója csak egy HTML-oldalt küld test nélkül, csak néhány szkriptcímkét, amelyeket aztán a böngésző az alkalmazás rendereléséhez használ.
A kliens-renderelt alkalmazások nagyszerűek az első oldal betöltése utáni minden későbbi felhasználói interakciónál. A szerveroldali renderelés lehetővé teszi számunkra, hogy elérjük az édes pontot az ügyfél-renderelt alkalmazások és a backend-renderelt alkalmazások közepén: az oldalt szerveroldalon generálják, de az oldallal való minden interakciót az oldal betöltése után kliensoldalon kezelik.
A szerveroldali renderelésnek azonban hátránya is van:
- mondhatjuk, hogy egy egyszerű SSR koncepció bizonyítása egyszerű, de az SSR összetettsége az alkalmazás összetettségével együtt nőhet
- egy nagy alkalmazás szerveroldali megjelenítése meglehetősen erőforrás-igényes lehet, és nagy terhelés esetén akár lassabb élményt is nyújthat, mint a kliensoldali renderelés, mivel egyetlen szűk keresztmetszeted van
Egy nagyon leegyszerűsített példa arra, hogy mi kell egy React alkalmazás szerveroldali rendereléséhez
Az SSR beállítások nagyon-nagyon összetetté válhatnak, és a legtöbb oktatóanyag már az elején be fogja sütni a Redux, React Router és sok más koncepciót.
Hogy megértsük, hogyan működik az SSR, kezdjük az alapoktól egy proof of concept megvalósításához.
Nyugodtan kihagyhatod ezt a bekezdést, ha csak az SSR-t biztosító könyvtárakat akarod megnézni, és nem foglalkozol az alapmunkával
Az alapvető SSR megvalósításához az Express-t fogjuk használni.
Ha új vagy az Expressben, vagy szükséged van egy kis felzárkóztatásra, nézd meg az ingyenes Express kézikönyvemet itt: https://flaviocopes.com/page/ebooks/.
Figyelmeztetés: az SSR bonyolultsága az alkalmazás bonyolultságával együtt nőhet. Ez a minimálisan szükséges beállítás egy alapvető React-alkalmazás megjelenítéséhez. Összetettebb igények esetén lehet, hogy egy kicsit több munkát kell végezned, vagy meg kell nézned az SSR könyvtárakat is a React számára.
Feltételezem, hogy egy React alkalmazást indítottál a create-react-app
segítségével. Ha csak próbálkozol, akkor most telepíts egyet a npx create-react-app ssr
segítségével.
Menj a fő app mappába a terminállal, majd futtasd:
npm install express
Az app könyvtáradban van egy sor mappa. Hozzon létre egy új mappát server
néven, majd menjen bele, és hozzon létre egy server.js
nevű fájlt.
A create-react-app
konvenciókat követve az alkalmazás a src/App.js
fájlban lakik. Betöltjük ezt a komponenst, és a ReactDOMServer.renderToString() segítségével egy karakterlánccá rendereljük, amit a react-dom
.
A ./build/index.html
fájl tartalmát megkapjuk, és a <div></div>
helyőrzőt, ami az a tag, ahol az alkalmazás alapértelmezés szerint horgol, kicseréljük a `<div>${ReactDOMServer.renderToString(<App />)}</div>
.
A build
mappában lévő összes tartalom úgy lesz kiszolgálva, ahogy van, statikusan az Express által.
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}`)})
Most az ügyfélalkalmazásban, a src/index.js
-ben, a ReactDOM.render()
meghívása helyett:
ReactDOM.render(<App />, document.getElementById('root'))
hívja a ReactDOM.hydrate()
-t, amely ugyanaz, de rendelkezik azzal a további képességgel, hogy a React betöltése után eseményhallgatókat csatoljon a meglévő jelöléshez:
ReactDOM.hydrate(<App />, document.getElementById('root'))
A Node.js kódot a Babelnek kell átfordítania, mivel a szerveroldali Node.js kód nem tud semmit a JSX-ről, sem az ES Modules-ről (amit a include
utasításokhoz használunk).
Telepítse ezt a 4 csomagot:
npm install @babel/register @babel/preset-env @babel/preset-react ignore-styles
ignore-styles
egy Babel segédprogram, amely megmondja neki, hogy a import
szintaxissal importált CSS fájlokat hagyja figyelmen kívül.
Hozzunk létre egy belépési pontot a server/index.js
-ben:
require('ignore-styles')require('@babel/register')({ ignore: , presets: })require('./server')
Elkészítjük a React alkalmazást, hogy a build/ mappát feltöltsük:
npm run build
és futtassuk ezt:
node server/index.js
Azt mondtam, hogy ez egy leegyszerűsített megközelítés, és így is van:
- nem kezeli megfelelően a képek renderelését, ha importokat használunk, amelyeknek Webpackre van szükségük a működéshez (és ez nagyon megnehezíti a folyamatot)
- nem kezeli az oldalfejléc metaadatait, ami elengedhetetlen a SEO és a közösségi megosztás szempontjából (többek között)
Szóval, bár ez egy jó példa arra, hogy a ReactDOMServer.renderToString()
és ReactDOM.hydrate
használatával elérjük ezt az alapvető szerveroldali renderelést, ez nem elég a valós használathoz.
Server Side Rendering using libraries
SSR-t nehéz jól csinálni, és a Reactnak nincs de-facto módja a megvalósítására.
Még mindig nagyon vitatható, hogy megéri-e a fáradtságot, a bonyolultságot és az overheadet az előnyök elérése érdekében, ahelyett, hogy más technológiát használnánk ezen oldalak kiszolgálására. Ez a vita a Redditen rengeteg véleményt tartalmaz ezzel kapcsolatban.
Ha a szerveroldali renderelés fontos kérdés, az én javaslatom az, hogy támaszkodjunk az előre elkészített könyvtárakra és eszközökre, amelyek a kezdetektől fogva ezt a célt tartják szem előtt.
Közelebbről a Next.js-t és a Gatsby-t javaslom.
Töltse le az ingyenes React kézikönyvemet
A 2021-es JavaScript Full-Stack Bootcamp már nyitva áll a regisztrációra jövő keddig! Ne hagyd ki ezt a lehetőséget, jelentkezz még ma!
Még több react tutorial:
- VS kód beállítása React fejlesztéshez
- React koncepció: Immutability
- Hogyan adjunk vissza több elemet JSX-ben
- React portálok
- Hogyan rendereljük a HTML-t Reactben
- A React tanulásának útiterve
- A jQuery-t vagy Reactet használjunk?
- Hogyan használjuk a useRef React horgot
- React Router, hogyan szerezhetünk adatokat egy dinamikus útvonalból