Cum sa implementati randarea pe server in aplicatia dvs React

De Rohit Kumar

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

Cum sa implementati randarea pe server in aplicatia dvs React

În acest tutorial, vom folosi redarea de pe server pentru a oferi un răspuns HTML atunci când un utilizator sau un crawler accesează o adresă URL a paginii. Vom gestiona ultimele solicitări din partea clientului.

De ce avem nevoie de ea?

Lasă-mă să te îndrum spre răspuns.

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

În Redare pe partea clientului, browserul dvs. descarcă o pagină HTML minimă. Redă JavaScript și umple conținutul în el.

Redare pe partea de server, pe de altă parte, redă componentele React pe server. Rezultatul este conținut HTML.

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

Contra Rendering React pe server

  • SSR poate îmbunătăți performanța dacă aplicația dvs. este mică. Dar poate degrada și 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 necesită mai mult timp pentru încărcare.
  • Crește complexitatea aplicației.

Când ar trebui să utilizați randarea pe server?

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

1. SEO

Fiecare site web vrea să apară în căutări. Corectează-mă daca greșesc.

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

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

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

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

1611663911 119 Cum sa implementati randarea pe server in aplicatia dvs React
Crawlerul Google nu redă React

O pagină goală.

Acesta a fost cel mai mare motiv pentru care am explorat randarea de pe server. Mai ales când este un pagina de piatră de temelie cum ar fi o pagină de destinație, un blog etc.

Pentru a verifica dacă Google redă site-ul dvs., vizitați:

Căutați tabloul de bord al consolei> Crawl> Preluare ca Google. Introduceți adresa URL a paginii sau lăsați-o goală pentru pagina de pornire.

Selectați FETCH AND RENDER. Odată finalizat, faceți clic pentru a vedea rezultatul.

2. Î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 ridicat.

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

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

Ați vizita din nou acel site?

Nu cred că ai face-o.

O altă îmbunătățire majoră este în Primul timp de interacțiune cu utilizatorul. Aceasta este diferența de timp de la momentul în care un utilizator lovește adresa URL până când vede conținut.

Iată comparația. L-am testat pe un Mac de dezvoltare.

React Rendered on Server

1611663911 546 Cum sa implementati randarea pe server in aplicatia dvs React
Raport de performanță SSR (Chrome)

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

React Rendered pe browserul clientului

1611663911 580 Cum sa implementati randarea pe server in aplicatia dvs React
Raportul de performanță al clientului (Chrome)

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

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

Cum functioneazã? – (4 pași simpli)

  • Creați un magazin Redux proaspăt la fiecare cerere.
  • Opțional, trimiteți câteva acțiuni.
  • Scoateți starea din magazin și efectuați SSR.
  • Trimiteți starea obținută în pasul anterior împreună cu răspunsul.

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

Înainte de a începe, clonează / descarcă exemplul complet din Github și folosiți-l ca referință.

Noțiuni introductive prin configurarea aplicației noastre

Mai întâi, deschideți editorul și shell-ul preferat. Creați un folder nou pentru aplicația dvs. Să începem.

npm init --yes

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

Instalați toate dependențele executând:

npm install

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

Babel transformă ESM și reacționează în nod și cod înțeles de browser.

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

{
  "presets": ["@babel/env", "@babel/react"]
}

webpack grupează 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:

const path = require('path');module.exports = {
    entry: {
        client: './src/client.js',
        bundle: './src/bundle.js'
    },
    output: {
        path: path.resolve(__dirname, 'assets'),
        filename: "[name].js"
    },
    module: {
        rules: [
            { test: /.js$/, exclude: /node_modules/, loader: "babel-loader" }
        ]
    }
}

Cele două fișiere ale procesului de compilare:

  1. assets/bundle.js – aplicație pură pentru client.
  2. assets/client.js – partener client pentru SSR.

src/ folderul conține codul sursă. Fișierele compilate Babel intră views/. views directorul va fi creat automat dacă nu este prezent.

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

Motivul este sintaxa diferența dintre ESM și CommonJS. În timp ce scriem React și Redux, folosim mult importul și exportul în toate fișierele.

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

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

Acum, Node le poate rula.

Copiați fișierele precodificate și statice

Dacă ați clonat deja depozitul, copiați din acesta. Altfel download fișier ssr-static.zip din Dropbox. Extrageți-l și păstrați aceste trei foldere în directorul aplicației. Iată ce conțin.

  1. Reacţiona App și componentele rezidă în src/components.
  2. Redux fișiere în src/redux/.
  3. assets/ & media/: Conține fișiere statice precum style.css și imagini.

Partea de server

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

1. 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, 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. Trece initialState la configureStore(). configureStore()returnează o nouă instanță Store. Ține-l în interiorul store variabil.
  2. Apel renderToString() , oferind aplicația noastră ca intrare. Redă aplicația noastră pe server și returnează codul HTML produs. Acum, variabila content stochează codul HTML.
  3. Scoateți starea din magazinul Redux apelând getState() pe store. Păstrați-l într-o variabilă preloadedState.
  4. Returnează content și preloadedState. Le vom transmite șablonului nostru pentru a obține pagina HTML finală.

2. src/template.js

template.js exportă o funcție. Este nevoie de title, state și content ca intrare. Le injectează în șablon și returnează documentul HTML final.

Pentru a trece de-a lungul stării, șablonul se atașează state la window.__STATE__ în interiorul unui <script> etichetă.

Acum puteți citi state din partea clientului accesând window.__STATE__.

Includem și companionul SSR assets/client.js aplicație din partea clientului într-o altă etichetă de script.

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

Partea clientului

Partea clientului este destul de simplă.

1. src / bundle.js

Așa scrieți React și Redux Provider înveliți. Este aplicația noastră pură din partea clientului. Fără 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')
);

2. src / client.js

Arata familiar? Da, nu este nimic special în afară de asta window.__STATE__. Tot ce trebuie să facem este să preluăm starea inițială de la window.__STATE__ și transmite-o la noi configureStore() funcționează 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ă examinăm modificările:

  1. A inlocui render() cu hydrate(). hydrate() este la fel ca render() dar este folosit pentru hidratarea elementelor redate de ReactDOMServer. Se asigură că conținutul este același pe server și client.
  2. Citiți starea din obiectul ferestrei globale window.__STATE__. Stocați-l într-o variabilă și ștergeți fișierul window.__STATE__.
  3. Creați un magazin proaspăt cu state ca initialState.

Totul este făcut aici.

Punând totul împreună

Index.js

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

De asemenea, declară un initialState variabil. L-am modelat cu date în assets/data.json fişier. Îl vom transmite către al nostru ssr() funcţie.

Notă: în timp ce faceți referire la un fișier care se află în interior src/ dintr-un dosar exterior src/ , folosiți normal require() și înlocuiți src/ de views/. Știți motivul (compilarea Babel).

Rutare

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

Construiți și alergați

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.

Sunteți gata să deveniți React Pro?

Încep o nouă serie de luni viitoare pentru a-ți dezvolta abilitățile React imediat.

Cum sa implementati randarea pe server in aplicatia dvs React
link de abonament de mai jos?

Vă mulțumesc că ați citit asta.

Dacă îți place și ți se pare util, urmărește-mă Stare de nervozitate & Flux web.