The 2021 JavaScript Full-Stack Bootcamp is NOW OPEN FOR SIGNUPS!
Server Side Rendering, zwany również SSR, jest zdolnością aplikacji JavaScript do renderowania na serwerze, a nie w przeglądarce.
Dlaczego w ogóle chcielibyśmy to zrobić?
- to pozwala twojej witrynie mieć szybszy czas ładowania pierwszej strony, co jest kluczem do dobrego doświadczenia użytkownika
- to jest niezbędne dla SEO: wyszukiwarki nie mogą (jeszcze?) skutecznie i poprawnie indeksować aplikacji, które renderują się wyłącznie po stronie klienta. Pomimo ostatnich ulepszeń w indeksowaniu w Google, są też inne wyszukiwarki, a Google nie jest w tym doskonały w każdym razie. Ponadto Google faworyzuje strony z szybkim czasem ładowania, a konieczność ładowania po stronie klienta nie jest dobra dla szybkości
- świetnie jest, gdy ludzie udostępniają stronę twojej witryny w mediach społecznościowych, ponieważ mogą łatwo zebrać metadane potrzebne do ładnego udostępnienia linku (obrazy, tytuł, opis…).)
Bez Server Side Rendering, wszystko co twój serwer wysyła to strona HTML bez ciała, tylko kilka znaczników skryptu, które są następnie używane przez przeglądarkę do renderowania aplikacji.
Aplikacje renderowane przez klienta są świetne w każdej kolejnej interakcji użytkownika po pierwszym załadowaniu strony. Server Side Rendering pozwala nam uzyskać słodki punkt w środku aplikacji renderowanych przez klienta i aplikacji renderowanych przez backend: strona jest generowana po stronie serwera, ale wszystkie interakcje ze stroną po jej załadowaniu są obsługiwane po stronie klienta.
Jednakże Server Side Rendering ma też swoje wady:
- uczciwie jest powiedzieć, że prosty dowód koncepcji SSR jest prosty, ale złożoność SSR może rosnąć wraz ze złożonością twojej aplikacji
- renderowanie dużej aplikacji po stronie serwera może być dość zasobochłonne, a przy dużym obciążeniu może nawet zapewnić wolniejsze doświadczenie niż renderowanie po stronie klienta, ponieważ masz jedno wąskie gardło
Bardzo uproszczony przykład tego, co jest potrzebne do renderowania po stronie serwera aplikacji React
UstawieniaSSR mogą stać się bardzo, bardzo złożone, a większość samouczków będzie piec w Redux, React Router i wiele innych koncepcji od samego początku.
Aby zrozumieć, jak działa SSR, zacznijmy od podstaw, aby zaimplementować dowód koncepcji.
Nie krępuj się pominąć tego akapitu, jeśli chcesz tylko zajrzeć do bibliotek, które zapewniają SSR i nie zawracać sobie głowy pracą u podstaw
Aby zaimplementować podstawowe SSR, użyjemy Express.
Jeśli jesteś nowy w Expressie, lub potrzebujesz trochę nadrobić zaległości, sprawdź mój darmowy podręcznik Expressu tutaj: https://flaviocopes.com/page/ebooks/.
Ostrzeżenie: złożoność SSR może rosnąć wraz ze złożonością Twojej aplikacji. Jest to minimalna konfiguracja do renderowania podstawowej aplikacji React. W przypadku bardziej złożonych potrzeb może być konieczne wykonanie nieco więcej pracy lub sprawdzenie bibliotek SSR dla React.
Zakładam, że rozpocząłeś aplikację React z create-react-app
. Jeśli dopiero próbujesz, zainstaluj jedną teraz używając npx create-react-app ssr
.
Przejdź do głównego folderu aplikacji za pomocą terminala, a następnie uruchom:
npm install express
Masz zestaw folderów w swoim katalogu aplikacji. Utwórz nowy folder o nazwie server
, a następnie wejdź do niego i utwórz plik o nazwie server.js
.
Podążając za konwencjami create-react-app
, aplikacja mieszka w pliku src/App.js
. Zamierzamy załadować ten komponent i wyrenderować go do łańcucha za pomocą ReactDOMServer.renderToString(), który jest dostarczany przez react-dom
.
Bierzesz zawartość pliku ./build/index.html
i zastępujesz <div></div>
placeholder, który jest tagiem, w którym aplikacja domyślnie hakuje, z `<div>${ReactDOMServer.renderToString(<App />)}</div>
.
Cała zawartość wewnątrz folderu build
będzie serwowana as-is, statycznie przez 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}`)})
Teraz, w aplikacji klienckiej, w twoim src/index.js
, zamiast wywoływania ReactDOM.render()
:
ReactDOM.render(<App />, document.getElementById('root'))
wywołaj ReactDOM.hydrate()
, który jest taki sam, ale ma dodatkową możliwość dołączania słuchaczy zdarzeń do istniejącego znacznika po załadowaniu React:
ReactDOM.hydrate(<App />, document.getElementById('root'))
Cały kod Node.js musi zostać przetransponowany przez Babel, ponieważ kod Node.js po stronie serwera nie wie nic o JSX, ani ES Modules (których używamy do deklaracji include
).
Zainstaluj te 4 pakiety:
npm install @babel/register @babel/preset-env @babel/preset-react ignore-styles
ignore-styles
jest narzędziem Babel, które powie mu, aby ignorował pliki CSS importowane przy użyciu składni import
.
Utwórzmy punkt wejścia w server/index.js
:
require('ignore-styles')require('@babel/register')({ ignore: , presets: })require('./server')
Zbuduj aplikację React, tak aby folder build/ był wypełniony:
npm run build
i uruchommy to:
node server/index.js
Powiedziałem, że jest to uproszczone podejście, i tak jest:
- nie obsługuje renderowania obrazów poprawnie podczas korzystania z importów, które wymagają Webpacka, aby działać (i co bardzo komplikuje proces)
- nie obsługuje metadanych nagłówka strony, które są niezbędne do celów SEO i udostępniania społecznościowego (między innymi)
Więc podczas gdy jest to dobry przykład użycia ReactDOMServer.renderToString()
i ReactDOM.hydrate
, aby uzyskać to podstawowe renderowanie po stronie serwera, nie jest to wystarczające do użycia w świecie rzeczywistym.
Server Side Rendering using libraries
SSR jest trudny do zrobienia dobrze, a React nie ma de-facto sposobu na jego implementację.
To wciąż jest bardzo dyskusyjne, czy warto się kłopotać, komplikować i nachodzić, aby uzyskać korzyści, zamiast używać innej technologii do obsługi tych stron. Ta dyskusja na Reddit ma wiele opinii w tym względzie.
Gdy Server Side Rendering jest ważną sprawą, moją sugestią jest poleganie na gotowych bibliotekach i narzędziach, które miały ten cel na uwadze od samego początku.
W szczególności, sugeruję Next.js i Gatsby.
Ściągnij mój darmowy React Handbook
The 2021 JavaScript Full-Stack Bootcamp IS NOW OPEN FOR SIGNUPS UNTIL NEXT TUESDAY! Nie przegap tej okazji, zapisz się już DZISIAJ!
Więcej tutoriali dotyczących Reacta:
- Konfiguracja kodu VS dla rozwoju React
- Koncepcja React: Immutability
- Jak zwracać wiele elementów w JSX
- Portale React
- Jak renderować HTML w React
- Mapa drogowa do nauki React
- Czy używać jQuery czy React?
- Jak używać haka useRef React
- React Router, jak uzyskać dane z dynamicznej trasy
.