Hoe implementeer je server-side rendering in je React-app in drie eenvoudige stappen

Door Rohit Kumar

Hier is wat we in deze tutorial gaan bouwen: een mooie React-kaart zoals deze.

In deze tutorial gaan we server-side rendering gebruiken om een HTML-respons te leveren wanneer een gebruiker of crawler een URL van een pagina opvraagt. Deze laatste verzoeken worden aan de client-zijde afgehandeld.

Waarom hebben we dit nodig?

Laat me u naar het antwoord leiden.

Wat is het verschil tussen client-side rendering en server-side rendering?

Bij client-side rendering downloadt uw browser een minimale HTML-pagina. Het rendert de JavaScript en vult de inhoud in.

Server-side rendering, aan de andere kant, rendert de React-componenten op de server. De uitvoer is HTML-inhoud.

U kunt deze twee combineren om een isomorfe app te maken.

Cons of Rendering React on the Server

  • SSR kan de prestaties verbeteren als uw toepassing klein is. Maar het kan ook de prestaties verminderen als het zwaar is.
  • Het verhoogt de responstijd (en het kan erger zijn als de server druk is).
  • Het verhoogt de responsgrootte, wat betekent dat de pagina er langer over doet om te laden.
  • Het verhoogt de complexiteit van de toepassing.

Wanneer moet je Server Side Rendering gebruiken?

Ondanks deze gevolgen van SSR, zijn er enkele situaties waarin je het kunt en moet gebruiken.

SEO

Elke website wil in zoekopdrachten verschijnen. Corrigeer me als ik het mis heb.

Helaas begrijpen crawlers van zoekmachines JavaScript nog niet.

Dit betekent dat ze een lege pagina zien, ongeacht hoe nuttig uw site is.

Velen zeggen dat Google’s crawler nu JavaScript rendert.

Om dit te testen, heb ik de app op Heroku ingezet. Dit is wat ik zag in de Google Search Console:

Google’s crawler rendert React niet

Een lege pagina.

Dit was de belangrijkste reden waarom ik server-side rendering heb onderzocht. Vooral als het een hoeksteenpagina is, zoals een landingspagina, blog, enzovoort.

Om te controleren of Google uw site rendert, gaat u naar:

Search Console Dashboard > Crawl > Fetch as Google. Voer de pagina URL of laat het leeg voor de homepage.

Selecteer FETCH EN RENDER. Eenmaal voltooid, klik om het resultaat te zien.

Verbeter de prestaties

In SSR, hangt de prestatie van de toepassing af van de middelen van de server en de snelheid van het netwerk van de gebruiker. Dit maakt het zeer nuttig voor inhoud zware sites.

Bijvoorbeeld, stel dat u een medium-price mobiele telefoon met trage internet snelheid. U probeert een site te openen die 4MB downloadt voordat u iets kunt zien.

Zou u in staat zijn om binnen 2-4 seconden iets op uw scherm te zien?

Zou u die site weer bezoeken?

Ik denk het niet.

Een andere grote verbetering is de First User Interaction Time. Dit is het verschil in tijd tussen het moment dat een gebruiker de URL aanklikt en het moment dat hij de inhoud ziet.

Hier is de vergelijking. Ik heb het getest op een ontwikkelings-Mac.

React Rendered on Server

SSR-prestatierapport (Chrome)

De eerste interactietijd is 300 ms. Hydrate eindigt na 400 ms. De belastingsevent wordt ongeveer na 500 ms afgesloten. U kunt dit zien in de bovenstaande afbeelding.

React Rendered on Client’s Browser

Client side performance report (Chrome)

De eerste interactietijd is 400 ms. De laadgebeurtenis wordt afgesloten na 470 ms.

Het resultaat spreekt voor zich. Er is een verschil van 100ms in de eerste gebruiker interactietijd voor zo’n kleine app.

Hoe werkt het? – (4 Eenvoudige Stappen)

  • Maak een verse Redux Store op elk verzoek.
  • Optioneel dispatch sommige acties.
  • Haal de staat uit de Store en voer SSR.
  • Verstuur de staat verkregen in de vorige stap samen met het antwoord.

We zullen de state gebruiken die in de response wordt doorgegeven voor het maken van de initiële state op client-side.

Voordat je aan de slag gaat, kloon/download het complete voorbeeld van Github en gebruik het als referentie.

Gaan van start met het opzetten van onze App

Opent u eerst uw favoriete editor en shell. Maak een nieuwe map voor uw applicatie. Laten we beginnen.

npm init --yes

Vul de details in. Nadat package.json is gemaakt, kopieer de afhankelijkheden en scripts hieronder erin.

Installeer alle afhankelijkheden door het uitvoeren van:

npm install

U moet Babel en webpack configureren voor ons build script om te werken.

Babel transformeert ESM en react in Node en browser-begrepen code.

Maak een nieuw bestand .babelrc en zet de regel hieronder erin.

{ "presets": }

webpack bundelt onze app en zijn afhankelijkheden in een enkel bestand. Maak een ander bestand webpack.config.js met de volgende code erin:

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: }}

Het bouwproces voert twee bestanden uit:

  1. assets/bundle.js – pure client side app.
  2. assets/client.js – client side companion voor SSR.

De src/ map bevat de broncode. De gecompileerde Babel bestanden gaan in views/. views directory wordt automatisch aangemaakt indien deze niet aanwezig is.

Waarom moeten we bronbestanden compileren?

De reden is het verschil in syntaxis tussen ESM & CommonJS. Tijdens het schrijven van React en Redux, we intensief gebruik van import en export in alle bestanden.

Helaas, ze werken niet in Node. Hier komt Babel om te redden. Het onderstaande script vertelt Babel om alle bestanden in de src directory te compileren en het resultaat in views.

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

Nu kan Node ze uitvoeren.

Kopieer voorgecodeerde & statische bestanden

Als je de repository al hebt gekloond, kopieer dan daaruit. Anders download je ssr-static.zip bestand van Dropbox. Pak het uit en bewaar deze drie mappen in je app directory. Hier is wat ze bevatten.

  1. React App en componenten bevindt zich in src/components.
  2. Redux-bestanden in src/redux/.
  3. assets/ & media/: Bevat statische bestanden zoals style.css en afbeeldingen.

Serverzijde

Maak twee nieuwe bestanden met de namen server.js en template.js binnen de src/ map.

src/server.js

De magie gebeurt hier. Dit is de code waar je naar op zoek was.

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 };};

In plaats van onze app te renderen, moeten we het in een functie verpakken en exporteren. De functie accepteert de initiële staat van de applicatie.

Hier is hoe het werkt.

  1. Pass initialState aan configureStore(). configureStore()returns een nieuwe Store instantie. Houd het in de store variabele.
  2. Roep renderToString() methode, met onze App als input. Het rendert onze app op de server en retourneert de geproduceerde HTML. Nu, de variabele content slaat de HTML.
  3. Haal de staat uit Redux Store door het aanroepen van getState() op store. Bewaar het in een variabele preloadedState.
  4. Return de content en preloadedState. We zullen deze doorgeven aan ons sjabloon om de uiteindelijke HTML-pagina te krijgen.

2. src/template.js

template.js exporteert een functie. Deze neemt title, state en content als invoer. Het injecteert ze in het sjabloon en retourneert het uiteindelijke HTML-document.

Om de status door te geven, koppelt het sjabloon state aan window.__STATE__ binnen een <script> tag.

Nu kunt u state aan de client-kant lezen door window.__STATE__ te benaderen.

We voegen ook de SSR companion assets/client.js client-side applicatie toe in een andere script tag.

Als u de pure client-versie aanvraagt, zet het alleen assets/bundle.js in de script-tag.

De client-kant

De client-kant is vrij eenvoudig.

src/bundle.js

Dit is hoe u de React en Redux Provider wrap schrijft. Het is onze pure client-side app. Geen trucs hier.

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

Kent u zich dat? Ja, er is niets speciaals behalve window.__STATE__. Alles wat we hoeven te doen is de initiële staat uit window.__STATE__ halen en doorgeven aan onze configureStore() functie als de initiële staat.

Laten we eens kijken naar ons nieuwe client-bestand:

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'));

Laten we eens kijken naar de wijzigingen:

  1. Vervang render() door hydrate(). hydrate() is hetzelfde als render() maar wordt gebruikt om elementen te hydrateren die door ReactDOMServer worden weergegeven. Het zorgt ervoor dat de inhoud hetzelfde is op de server en de client.
  2. Leest de status van het globale venster object window.__STATE__. Sla het op in een variabele en verwijder de window.__STATE__.
  3. Maak een nieuwe store met state als initialState.

Alles klaar hier.

Het allemaal samenvoegen

Index.js

Dit is het beginpunt van onze applicatie. Het behandelt verzoeken en templating.

Het verklaart ook een initialState variabele. Ik heb het gemodelleerd met gegevens in het assets/data.json -bestand. We zullen het doorgeven aan onze ssr() functie.

Note: Tijdens het verwijzen naar een bestand dat binnen src/ staat vanuit een bestand buiten src/, gebruik dan normaal require() en vervang src/ door views/. U kent de reden (Babel compile).

Routing

  1. /: Standaard server-rendered homepage.
  2. /client: Zuiver client-side rendering voorbeeld.
  3. /exit: Server stop knop. Alleen beschikbaar in development.

Build & Run

Het is tijd om onze applicatie te bouwen en te draaien. We kunnen dit doen met een enkele regel code.

npm run build && npm run start

Nu draait de applicatie op http://localhost:3000.

Klaar om een React Pro te worden?

Ik start een nieuwe serie vanaf volgende week maandag om je React vaardigheden te laten knallen, onmiddellijk.

inschrijvingslink hieronder ?

Bedankt voor het lezen.

Als je het leuk en nuttig vindt, volg me dan op Twitter & Webflow.

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.