Wie man in drei einfachen Schritten serverseitiges Rendering in seine React-App implementiert

Von Rohit Kumar

In diesem Tutorial werden wir eine schöne React-Karte wie diese bauen.

In diesem Tutorial werden wir serverseitiges Rendering verwenden, um eine HTML-Antwort zu liefern, wenn ein Benutzer oder Crawler eine Seiten-URL aufruft. Letztere Anfragen werden auf der Client-Seite bearbeitet.

Warum brauchen wir das?

Lassen Sie mich Ihnen die Antwort geben.

Was ist der Unterschied zwischen Client-seitigem Rendering und Server-seitigem Rendering?

Beim Client-seitigen Rendering lädt Ihr Browser eine minimale HTML-Seite herunter. Er rendert das JavaScript und füllt den Inhalt darin ein.

Beim serverseitigen Rendering hingegen werden die React-Komponenten auf dem Server gerendert. Die Ausgabe ist HTML-Inhalt.

Sie können diese beiden Verfahren kombinieren, um eine isomorphe Anwendung zu erstellen.

Nachteile des Renderings von React auf dem Server

  • SSR kann die Leistung verbessern, wenn Ihre Anwendung klein ist. Aber es kann auch die Leistung verschlechtern, wenn sie schwer ist.
  • Es erhöht die Antwortzeit (und es kann schlimmer sein, wenn der Server beschäftigt ist).
  • Es erhöht die Antwortgröße, was bedeutet, dass die Seite länger zum Laden braucht.
  • Es erhöht die Komplexität der Anwendung.

Wann sollte man Server Side Rendering verwenden?

Trotz dieser Folgen von SSR gibt es einige Situationen, in denen man es verwenden kann und sollte.

SEO

Jede Website möchte in Suchergebnissen erscheinen. Korrigieren Sie mich, wenn ich falsch liege.

Leider verstehen Suchmaschinen-Crawler JavaScript noch nicht.

Das bedeutet, dass sie eine leere Seite sehen, egal wie hilfreich Ihre Website ist.

Viele Leute sagen, dass Googles Crawler jetzt JavaScript rendert.

Um dies zu testen, habe ich die App auf Heroku bereitgestellt. Hier ist, was ich in der Google Search Console gesehen habe:

Google’s crawler does not render React

Eine leere Seite.

Das war der Hauptgrund, warum ich das serverseitige Rendering erforscht habe. Vor allem, wenn es sich um eine Eckpfeiler-Seite wie eine Landing Page, einen Blog usw. handelt.

Um zu überprüfen, ob Google Ihre Seite rendert, besuchen Sie:

Search Console Dashboard > Crawl > Fetch as Google. Geben Sie die URL der Seite ein oder lassen Sie sie für die Startseite leer.

Wählen Sie FETCH AND RENDER. Wenn Sie fertig sind, klicken Sie auf , um das Ergebnis zu sehen.

Leistung verbessern

In SSR hängt die Leistung der Anwendung von den Ressourcen des Servers und der Netzwerkgeschwindigkeit des Benutzers ab. Das macht es sehr nützlich für inhaltsintensive Websites.

Angenommen, Sie haben ein Mobiltelefon mittlerer Preisklasse mit langsamer Internet-Geschwindigkeit. Sie versuchen, auf eine Website zuzugreifen, die 4 MB Daten herunterlädt, bevor Sie etwas sehen können.

Würden Sie innerhalb von 2-4 Sekunden etwas auf Ihrem Bildschirm sehen?

Würden Sie diese Website wieder besuchen?

Ich glaube nicht.

Eine weitere wichtige Verbesserung ist die First User Interaction Time. Das ist der Zeitunterschied zwischen dem Aufrufen der URL und der Anzeige des Inhalts.

Hier ist der Vergleich. Ich habe es auf einem Entwicklungs-Mac getestet.

React Rendered on Server

SSR-Leistungsbericht (Chrome)

Die erste Interaktionszeit beträgt 300 ms. Hydrate wird bei 400 ms beendet. Das Ladeereignis wird nach etwa 500 ms beendet. Sie können dies anhand des obigen Bildes sehen.

React Rendered on Client’s Browser

Client side performance report (Chrome)

Die erste Interaktionszeit beträgt 400ms. Das Ladeereignis wird bei 470 ms beendet.

Das Ergebnis spricht für sich selbst. Es gibt einen Unterschied von 100ms in der ersten Benutzerinteraktionszeit für eine so kleine App.

Wie funktioniert es? – (4 einfache Schritte)

  • Bei jeder Anfrage einen neuen Redux-Store erstellen.
  • Optional einige Aktionen versenden.
  • Den Status aus dem Store holen und SSR durchführen.
  • Den im vorherigen Schritt erhaltenen Status zusammen mit der Antwort senden.

Wir werden den in der Antwort übergebenen Status verwenden, um den anfänglichen Status auf der Client-Seite zu erstellen.

Bevor Sie beginnen, klonen Sie das vollständige Beispiel von Github und verwenden Sie es als Referenz.

Beginnen Sie mit dem Einrichten unserer App

Zunächst öffnen Sie Ihren bevorzugten Editor und Ihre Shell. Erstellen Sie einen neuen Ordner für Ihre Anwendung. Fangen wir an.

npm init --yes

Füllen Sie die Details aus. Nachdem package.json erstellt wurde, kopieren Sie die folgenden Abhängigkeiten und Skripte hinein.

Installieren Sie alle Abhängigkeiten, indem Sie Folgendes ausführen:

npm install

Sie müssen Babel und Webpack konfigurieren, damit unser Build-Skript funktioniert.

Babel wandelt ESM und React in Node- und Browser-verständlichen Code um.

Erstelle eine neue Datei .babelrc und füge die folgende Zeile darin ein.

{ "presets": }

webpack bündelt unsere App und ihre Abhängigkeiten in einer einzigen Datei. Erstellen Sie eine weitere Datei webpack.config.js mit folgendem Code:

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

Der Build-Prozess gibt zwei Dateien aus:

  1. assets/bundle.js – reine clientseitige Anwendung.
  2. assets/client.js – clientseitiger Begleiter für SSR.

Der src/ Ordner enthält den Quellcode. Die von Babel kompilierten Dateien werden in views/ abgelegt. Das Verzeichnis views wird automatisch erstellt, wenn es nicht vorhanden ist.

Warum müssen wir die Quelldateien kompilieren?

Der Grund ist der Syntaxunterschied zwischen ESM & CommonJS. Beim Schreiben von React und Redux verwenden wir in allen Dateien häufig import und export.

Leider funktionieren sie in Node nicht. Hier kommt Babel zur Rettung. Das folgende Skript weist Babel an, alle Dateien im Verzeichnis src zu kompilieren und das Ergebnis in views.

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

Jetzt kann Node sie ausführen.

Copy Precoded & Static files

Wenn Sie das Repository bereits geklont haben, kopieren Sie es. Andernfalls laden Sie die Datei ssr-static.zip von Dropbox herunter. Entpacken Sie sie und behalten Sie diese drei Ordner in Ihrem App-Verzeichnis. Hier ist, was sie enthalten.

  1. React App und Komponenten befinden sich in src/components.
  2. Redux-Dateien in src/redux/.
  3. assets/ & media/: Enthält statische Dateien wie style.css und Bilder.

Serverseite

Erstelle zwei neue Dateien mit den Namen server.js und template.js im Ordner src/.

src/server.js

Hier passiert Magie. Dies ist der Code, nach dem Sie gesucht haben.

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

Anstatt unsere Anwendung zu rendern, müssen wir sie in eine Funktion verpacken und exportieren. Die Funktion nimmt den Anfangszustand der Anwendung an.

So funktioniert es.

  1. Pass initialState zu configureStore(). configureStore()Gibt eine neue Store-Instanz zurück. Halten Sie sie in der Variablen store.
  2. Rufen Sie die Methode renderToString() auf und geben Sie unsere App als Eingabe ein. Sie rendert unsere App auf dem Server und gibt das erzeugte HTML zurück. Jetzt speichert die Variable content das HTML.
  3. Hole den Status aus dem Redux Store, indem du getState() auf store aufrufst. Behalte ihn in der Variable preloadedState.
  4. Rückgabe von content und preloadedState. Wir werden diese an unsere Vorlage übergeben, um die endgültige HTML-Seite zu erhalten.

2. src/template.js

template.js exportiert eine Funktion. Sie nimmt title, state und content als Eingabe. Sie injiziert sie in die Vorlage und gibt das endgültige HTML-Dokument zurück.

Um den Status weiterzugeben, fügt die Vorlage state an window.__STATE__ innerhalb eines <script>-Tags an.

Jetzt können Sie state auf der Client-Seite lesen, indem Sie auf window.__STATE__ zugreifen.

Wir binden auch die SSR-Begleitanwendung assets/client.js auf der Client-Seite in ein anderes Skript-Tag ein.

Wenn Sie die reine Client-Version anfordern, wird nur assets/bundle.js in das Skript-Tag eingefügt.

Die Client-Seite

Die Client-Seite ist ziemlich einfach.

src/bundle.js

So schreiben Sie die React- und Redux Provider-Verpackung. Es ist unsere reine Client-seitige App. Keine Tricks 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

Kommt dir bekannt vor? Ja, es gibt nichts Besonderes außer window.__STATE__. Alles, was wir tun müssen, ist, den Anfangszustand aus window.__STATE__ zu nehmen und ihn an unsere configureStore() Funktion als Anfangszustand zu übergeben.

Lassen Sie uns einen Blick auf unsere neue Client-Datei werfen:

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

Lassen Sie uns die Änderungen überprüfen:

  1. Ersetzen Sie render() durch hydrate(). hydrate() ist dasselbe wie render(), wird aber verwendet, um Elemente zu hydrieren, die von ReactDOMServer gerendert werden. Es stellt sicher, dass der Inhalt auf dem Server und dem Client derselbe ist.
  2. Lesen Sie den Status aus dem globalen Fensterobjekt window.__STATE__. Speichere ihn in einer Variablen und lösche window.__STATE__.
  3. Erstelle einen neuen Speicher mit state als initialState.

Alles ist hier fertig.

Alles zusammenfügen

Index.js

Dies ist der Einstiegspunkt unserer Anwendung. Es behandelt Anfragen und Vorlagen.

Es deklariert auch eine initialState Variable. Ich habe sie mit Daten in der assets/data.json Datei modelliert. Wir werden sie an unsere ssr()-Funktion übergeben.

Hinweis: Wenn Sie eine Datei innerhalb von src/ von einer Datei außerhalb von src/ referenzieren, verwenden Sie das normale require() und ersetzen src/ durch views/. Sie kennen den Grund (Babel compile).

Routing

  1. /: Standardmäßig server-gerenderte Homepage.
  2. /client: Reines Client-seitiges Rendering-Beispiel.
  3. /exit: Server-Stopp-Schaltfläche. Nur in der Entwicklung verfügbar.

Build & Run

Es ist Zeit, unsere Anwendung zu erstellen und auszuführen. Wir können dies mit einer einzigen Codezeile tun.

npm run build && npm run start

Jetzt läuft die Anwendung auf http://localhost:3000.

Bereit, ein React-Profi zu werden?

Ab nächsten Montag beginne ich mit einer neuen Serie, um deine React-Fähigkeiten sofort zu verbessern.

Abonnement-Link unten ?

Danke, dass Sie das gelesen haben.

Wenn es Ihnen gefällt und Sie es nützlich finden, folgen Sie mir auf Twitter & Webflow.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.