Cum să implementați redarea pe partea serverului în aplicația React în trei pași simpli

De Rohit Kumar

Iată ce vom construi în acest tutorial: o carte React frumoasă ca aceasta.

În acest tutorial, vom folosi redarea pe partea serverului pentru a livra un răspuns HTML atunci când un utilizator sau un crawler accesează un URL de pagină. Ne vom ocupa de aceste din urmă solicitări pe partea clientului.

De ce avem nevoie de ea?

Lăsați-mă să vă ghidez spre răspuns.

Care este diferența dintre redarea pe partea de client și redarea pe partea de server?

În redarea pe partea de client, browserul dumneavoastră descarcă o pagină HTML minimă. Acesta redă JavaScript-ul și umple conținutul în ea.

Rendarea pe partea serverului, pe de altă parte, redă componentele React pe server. Ieșirea este conținut HTML.

Puteți combina aceste două pentru a crea o aplicație izomorfă.

Cons of Rendering React on the Server

  • SSR poate îmbunătăți performanța dacă aplicația dvs. este mică. Dar poate, de asemenea, să degradeze performanța dacă este grea.
  • Crește timpul de răspuns (și poate fi mai rău dacă serverul este ocupat).
  • Crește dimensiunea răspunsului, ceea ce înseamnă că pagina durează mai mult să se încarce.
  • Crește complexitatea aplicației.

Când ar trebui să folosiți Server Side Rendering?

În ciuda acestor consecințe ale SSR, există unele situații în care puteți și ar trebui să îl folosiți.

SEO

Care site web dorește să apară în căutări. Corectați-mă dacă greșesc.

Din păcate, crawlerele motoarelor de căutare nu înțeleg/prestează încă JavaScript.

Aceasta înseamnă că ei văd o pagină goală, indiferent cât de util este site-ul dumneavoastră.

Mulți oameni spun că crawlerul Google redă acum JavaScript.

Pentru a testa acest lucru, am implementat aplicația pe Heroku. Iată ce am văzut în Google Search Console:

Google’s crawler nu redă React

O pagină goală.

Acesta a fost cel mai mare motiv pentru care am explorat redarea pe partea serverului. Mai ales atunci când este vorba de o pagină de piatră de temelie, cum ar fi o pagină de destinație, un blog și așa mai departe.

Pentru a verifica dacă Google redă site-ul dvs. Introduceți URL-ul paginii sau lăsați-l gol pentru pagina de pornire.

Select FETCH AND RENDER. După ce ați terminat, faceți clic pentru a vedea rezultatul.

Îmbunătățiți performanța

În SSR, performanța aplicației depinde de resursele serverului și de viteza rețelei utilizatorului. Acest lucru îl face foarte util pentru site-urile cu conținut intensiv.

De exemplu, să spunem că aveți un telefon mobil de preț mediu cu o viteză de internet lentă. Încercați să accesați un site care descarcă 4MB de date înainte de a putea vedea ceva.

Ați putea vedea ceva pe ecran în 2-4 secunde?

Ați mai vizita acel site din nou?

Nu cred că ați face-o.

O altă îmbunătățire majoră este în timpul de interacțiune cu primul utilizator. Aceasta este diferența de timp dintre momentul în care un utilizator accesează URL-ul și momentul în care vede conținutul.

Iată comparația. Am testat-o pe un Mac de dezvoltare.

React Rendered on Server

Raport de performanță SSR (Chrome)

Primul timp de interacțiune este de 300ms. Hidratarea se termină la 400ms. Evenimentul de încărcare iese la aproximativ 500ms. Puteți vedea acest lucru verificând imaginea de mai sus.

React Rendered on Client’s Browser

Raport de performanță pe partea clientului (Chrome)

Primul timp de interacțiune este de 400ms. Evenimentul de încărcare iese la 470ms.

Rezultatul vorbește de la sine. Există o diferență de 100ms în timpul primei interacțiuni cu utilizatorul pentru o aplicație atât de mică.

Cum funcționează? – (4 pași simpli)

  • Creați un Redux Store proaspăt la fiecare solicitare.
  • Opțional, expediați unele acțiuni.
  • Obțineți starea din Store și efectuați SSR.
  • Întoarceți starea obținută în pasul anterior împreună cu răspunsul.

Vom folosi starea transmisă în răspuns pentru crearea stării inițiale pe partea clientului.

Înainte de a începe, clonați/descărcați exemplul complet de pe Github și folosiți-l ca referință.

Începeți prin configurarea aplicației noastre

În primul rând, deschideți editorul dvs. preferat și shell-ul. Creați un nou dosar pentru aplicația dvs. Să începem.

npm init --yes

Completați detaliile. După ce package.json este creat, copiați dependențele și scripturile de mai jos în el.

Instalați toate dependențele rulând:

npm install

Trebuie să configurați Babel și webpack pentru ca scriptul nostru de construcție să funcționeze.

Babel transformă ESM și react în cod Node și înțeles de browser.

Creați un nou fișier .babelrc și puneți în el linia de mai jos.

{ "presets": }

webpack reunește aplicația noastră și dependențele sale într-un singur fișier. Creați un alt fișier webpack.config.js cu următorul cod în el:

const path = require('path');module.exports = { entry: { client: './src/client.js', bundle: './src/bundle.js' }, output: { path: path.resolve(__dirname, 'assets'), filename: ".js" }, module: { rules: }}

Procesul de compilare produce două fișiere:

  1. assets/bundle.js – aplicația pură de partea clientului.
  2. assets/client.js – companion de partea clientului pentru SSR.

Dosarul src/ conține codul sursă. Fișierele compilate Babel merg în views/. Directorul views va fi creat automat dacă nu este prezent.

De ce trebuie să compilăm fișierele sursă?

Motivul este diferența de sintaxă dintre ESM & CommonJS. În timp ce scriem React și Redux, folosim foarte mult import și export în toate fișierele.

Din păcate, acestea nu funcționează în Node. Aici vine Babel să ne salveze. Scriptul de mai jos îi spune lui Babel să compileze toate fișierele din directorul src și să pună rezultatul în views.

"babel": "babel src -d views",

Acum, Node le poate rula.

Copiază fișierele statice precodificate &

Dacă ați clonat deja depozitul, copiați din el. În caz contrar, descărcați fișierul ssr-static.zip din Dropbox. Extrageți-l și păstrați aceste trei foldere în interiorul directorului dvs. de aplicații. Iată ce conțin ele.

  1. React App și componentele rezidă în src/components.
  2. Filele Redux în src/redux/.
  3. assets/ & media/: Conține fișiere statice, cum ar fi style.css și imagini.

Server Side

Creați două fișiere noi numite server.js și template.js în interiorul folderului src/.

src/server.js

Magia se întâmplă aici. Acesta este codul pe care l-ați căutat.

import React from 'react';import { renderToString } from 'react-dom/server';import { Provider } from 'react-redux';import configureStore from './redux/configureStore';import App from './components/app';module.exports = function render(initialState) { // Model the initial state const store = configureStore(initialState); let content = renderToString(<Provider store={store} ><App /></Provider>); const preloadedState = store.getState(); return { content, preloadedState };};

În loc să redăm aplicația noastră, trebuie să o înfășurăm într-o funcție și să o exportăm. Funcția acceptă starea inițială a aplicației.

Iată cum funcționează.

  1. Pasați initialState la configureStore(). configureStore()returnează o nouă instanță Store. Țineți-o în interiorul variabilei store.
  2. Apelează metoda renderToString(), furnizând aplicația noastră ca intrare. Aceasta redă aplicația noastră pe server și returnează HTML-ul produs. Acum, variabila content stochează HTML-ul.
  3. Obțineți starea din Redux Store prin apelarea getState() pe store. Păstrați-o într-o variabilă preloadedState.
  4. Întoarceți content și preloadedState. Le vom trece acestea în șablonul nostru pentru a obține pagina HTML finală.

2. src/template.js

template.jsexportă o funcție. Aceasta primește ca intrare title, state și content. Le injectează în șablon și returnează documentul HTML final.

Pentru a transmite starea, șablonul atașează state la window.__STATE__ în interiorul unei etichete <script>.

Acum puteți citi state pe partea de client accesând window.__STATE__.

De asemenea, includem aplicația SSR companion assets/client.js pe partea de client într-o altă etichetă de script.

Dacă solicitați versiunea pur client, aceasta pune doar assets/bundle.js în interiorul tag-ului de script.

Latura client

Latura client este destul de simplă.

src/bundle.js

Acesta este modul în care se scrie înfășurarea React și Redux Provider. Este aplicația noastră pură pe partea de client. Nu există trucuri aici.

import React from 'react';import { render } from 'react-dom';import { Provider } from 'react-redux';import configureStore from './redux/configureStore';import App from './components/app';const store = configureStore();render( <Provider store={store} > <App /> </Provider>, document.querySelector('#app'));

src/client.js

Vă pare cunoscut? Da, nu este nimic special, cu excepția window.__STATE__. Tot ce trebuie să facem este să luăm starea inițială din window.__STATE__ și să o transmitem funcției noastre configureStore() ca stare inițială.

Să aruncăm o privire la noul nostru fișier client:

import React from 'react';import { hydrate } from 'react-dom';import { Provider } from 'react-redux';import configureStore from './redux/configureStore';import App from './components/app';const state = window.__STATE__;delete window.__STATE__;const store = configureStore(state);hydrate( <Provider store={store} > <App /> </Provider>, document.querySelector('#app'));

Să trecem în revistă modificările:

  1. Înlocuiți render() cu hydrate(). hydrate() este la fel ca render(), dar este folosit pentru a hidrata elementele redate de ReactDOMServer. Se asigură că conținutul este același pe server și pe client.
  2. Citește starea din obiectul global fereastră window.__STATE__. Stocați-l într-o variabilă și ștergeți window.__STATE__.
  3. Creați un nou magazin cu state ca initialState.

Totul este gata aici.

Punând totul laolaltă

Index.js

Acesta este punctul de intrare al aplicației noastre. Se ocupă de cereri și de modelare.

De asemenea, declară o variabilă initialState. Am modelat-o cu datele din fișierul assets/data.json . O vom trece la funcția noastră ssr().

Nota: În timp ce se face referire la un fișier care se află în interiorul src/ dintr-un fișier din afara src/ , folosiți require() normal și înlocuiți src/ cu views/. Cunoașteți motivul (compilarea Babel).

Routing

  1. /: În mod implicit pagina de pornire redată de server.
  2. /client: Exemplu de randare pură pe partea clientului.
  3. /exit: Buton de oprire a serverului. Disponibil numai în dezvoltare.

Build & Run

Este timpul să construim și să rulăm aplicația noastră. Putem face acest lucru cu o singură linie de cod.

npm run build && npm run start

Acum, aplicația rulează la http://localhost:3000.

Pregătiți să deveniți un React Pro?

Încep o nouă serie începând de lunea viitoare pentru a vă pune la punct abilitățile React, imediat.

Legătura de abonare de mai jos ?

Mulțumesc că ați citit asta.

Dacă vă place și vi se pare util, urmăriți-mă pe Twitter & Webflow.

.

Lasă un răspuns

Adresa ta de email nu va fi publicată.