ReactJS serverseitiges Rendering vs. clientseitiges Rendering

120

Ich habe gerade angefangen, ReactJS zu studieren und festgestellt, dass es zwei Möglichkeiten gibt, Seiten zu rendern: serverseitig und clientseitig. Aber ich kann nicht verstehen, wie man es zusammen benutzt. Gibt es zwei verschiedene Möglichkeiten, um die Anwendung zu erstellen, oder können sie zusammen verwendet werden?

Wenn wir es zusammen verwenden können, wie geht das? Müssen wir dieselben Elemente auf der Server- und der Client-Seite duplizieren? Oder können wir einfach die statischen Teile unserer Anwendung auf dem Server und die dynamischen Teile auf der Clientseite erstellen, ohne eine Verbindung zur Serverseite herzustellen, die bereits vorgerendert wurde?

Simcha
quelle
1
Kurze Antwort, NEIN - Sie können entkoppeln, statisches HTML senden und es im Client-Rendering vollständig ändern. Habe Details in meine Antwort aufgenommen.
Kira

Antworten:

108

Für eine bestimmte Website / Webanwendung können Sie entweder clientseitig , serverseitig oder beides verwenden .

Client-Seite

Hier führen Sie ReactJS vollständig im Browser aus. Dies ist die einfachste Einrichtung und enthält die meisten Beispiele (einschließlich der auf http://reactjs.org ). Der vom Server gerenderte anfängliche HTML-Code ist ein Platzhalter und die gesamte Benutzeroberfläche wird im Browser gerendert, sobald alle Ihre Skripte geladen sind.

Serverseitig

Stellen Sie sich ReactJS hier als serverseitige Template-Engine vor (wie Jade, Lenker usw.). Der vom Server gerenderte HTML-Code enthält die Benutzeroberfläche, wie sie sein sollte, und Sie warten nicht auf das Laden von Skripten. Ihre Seite kann von einer Suchmaschine indiziert werden (wenn kein Javascript ausgeführt wird).

Da die Benutzeroberfläche auf dem Server gerendert wird, funktioniert keiner Ihrer Ereignishandler und es gibt keine Interaktivität (Sie haben eine statische Seite).

Beide

Hier befindet sich das erste Rendern auf dem Server. Daher hat der vom Browser empfangene HTML-Code die Benutzeroberfläche so, wie sie sein sollte. Sobald die Skripte geladen sind, wird das virtuelle DOM erneut gerendert, um die Ereignishandler Ihrer Komponenten einzurichten.

Hier müssen Sie sicherstellen, dass Sie genau dasselbe virtuelle DOM (Root-ReactJS-Komponente) mit demselben propsrendern, das Sie zum Rendern auf dem Server verwendet haben. Andernfalls beschwert sich ReactJS, dass die serverseitigen und clientseitigen virtuellen DOMs nicht übereinstimmen.

Da ReactJS die virtuellen DOMs zwischen erneuten Rendern unterscheidet, ist das reale DOM nicht mutiert. Nur die Ereignishandler sind an die realen DOM-Elemente gebunden.

Gautham Badhrinathan
quelle
1
Also im Fall von "beiden" muss ich den gleichen Code zweimal schreiben "einen für das Server-Rendering und einen, um dieses DOM auf dem Client zu reproduzieren? Richtig?
Simcha
10
Sie müssen laufen zweimal den gleichen Code. Einmal auf dem Server und einmal auf dem Client. Sie müssen jedoch Ihre Komponenten schreiben, um dies zu berücksichtigen - z. B. sollten Sie keine asynchronen Daten abrufen componentWillMount(), da dies sowohl den Client als auch den Server ausführt. Sie benötigen außerdem eine Strategie, um Daten im Voraus auf dem Server abzurufen und für das erste Rendern auf dem Client verfügbar zu machen, um sicherzustellen, dass Sie dieselbe Ausgabe erhalten.
Jonny Buchanan
3
Sie können auch überprüfen, ob der ausgeführte Code serverseitig oder clientseitig ist, typeof window == "undefined"und dann Ihre Daten entsprechend abrufen.
Gautham Badhrinathan
Haben Sie einen Link zu einem Beispiel, das zu Ihrer Implementierung passt?
Sawtaytoes
1
@IanW In diesem Fall ist der vom Server zurückgegebene HTML-Code in der Regel sehr "bloß". Sie importieren einfach Ihr JavaScript und Ihre Stile und enthalten einen <div>, in den React schreibt.
Matt Holland
48

Bildquelle: Walmart Labs Engineering Blog

SSR

CSR

NB: SSR (Server Side Rendering), CSR (Client Side Rendering).

Der Hauptunterschied besteht darin, dass bei SSR die Serverantwort auf den Client-Browser den HTML-Code der zu rendernden Seite enthält. Es ist auch wichtig zu beachten, dass die Seite mit SSR schneller gerendert wird. Die Seite ist erst für die Benutzerinteraktion bereit, wenn JS-Dateien heruntergeladen wurden und der Browser React ausgeführt hat.

Ein Nachteil ist, dass der SSR-TTFB (Time to First Byte) etwas länger sein kann. Verständlicherweise, da der Server einige Zeit zum Erstellen des HTML-Dokuments benötigt, was wiederum die Antwortgröße des Servers erhöht.

JSON C11
quelle
4

Ich habe mich tatsächlich einiges über die gleichen Nachforschungen gewundert, und während die Antwort, nach der Sie suchen, in den Kommentaren angegeben wurde, sollte sie meiner Meinung nach prominenter sein, daher schreibe ich diesen Beitrag (den ich aktualisieren werde, sobald ich einen finden kann besserer Weg, da ich die Lösung architektonisch zumindest fragwürdig finde).

Sie müssten Ihre Komponenten in beide Richtungen schreiben und so ifüberall Schalter setzen , um festzustellen, ob Sie sich auf dem Client oder dem Server befinden, und dann entweder als DB-Abfrage (oder was auch immer auf dem Server angemessen ist) oder als REST-Aufruf (auf dem Server) ausführen Klient). Dann müssten Sie Endpunkte schreiben, die Ihre Daten generieren und sie dem Client zur Verfügung stellen, und los geht's.

Ich freue mich wieder über eine sauberere Lösung.

SGD
quelle
2

Gibt es zwei verschiedene Möglichkeiten, um die Anwendung zu erstellen, oder können sie zusammen verwendet werden?

Sie können zusammen verwendet werden.

Wenn wir es zusammen verwenden können, wie geht das? Müssen wir auf Server- und Client-Seite dieselben Elemente duplizieren? Oder können wir einfach die statischen Teile unserer Anwendung auf dem Server und die dynamischen Teile auf der Clientseite erstellen, ohne eine Verbindung zur Serverseite herzustellen, die bereits vorgerendert wurde?

Es ist besser, dasselbe Layout zu rendern, um Reflow- und Repaint-Vorgänge zu vermeiden. Weniger Flimmern / Blinken, Ihre Seite wird glatter. Dies ist jedoch keine Einschränkung. Sie können das SSR-HTML sehr gut zwischenspeichern (etwas, das Electrode tut, um die Antwortzeit zu verkürzen) / ein statisches HTML senden, das vom CSR überschrieben wird (clientseitiges Rendern).

Wenn Sie gerade erst mit SSR beginnen, würde ich empfehlen, einfach zu starten. SSR kann sehr schnell sehr komplex werden. Wenn Sie HTML auf dem Server erstellen, verlieren Sie den Zugriff auf Objekte wie Fenster, Dokumente (Sie haben diese auf dem Client), verlieren die Fähigkeit, asynchrone Vorgänge zu integrieren (sofort einsatzbereit) und im Allgemeinen viele Code-Änderungen, um Ihren Code SSR-kompatibel zu machen ( da du webpack verwenden musst, um deine bundle.js zu packen). Dinge wie CSS-Importe, erfordern vs Import beginnen plötzlich, Sie zu beißen (dies ist nicht der Fall in der Standard-React-App ohne Webpack).

Das allgemeine Muster von SSR sieht so aus. Ein Express-Server, der Anforderungen bedient:

const app = Express();
const port = 8092;

// This is fired every time the server side receives a request
app.use(handleRender);
function handleRender(req, res) {
    const fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl;
    console.log('fullUrl: ', fullUrl);
    console.log('req.url: ', req.url);

    // Create a new Redux store instance
    const store = createStore(reducerFn);

    const urlToRender = req.url;
    // Render the component to a string
    const html = renderToString(
        <Provider store={store}>
            <StaticRouter location={urlToRender} context={{}}>
                {routes}
            </StaticRouter>
        </Provider>
    );
    const helmet = Helmet.renderStatic();

    // Grab the initial state from our Redux store
    const preloadedState = store.getState();

    // Send the rendered page back to the client
    res.send(renderFullPage(helmet, html, preloadedState));
}

Mein Vorschlag an Leute, die mit SSR beginnen, wäre, statisches HTML bereitzustellen. Sie können das statische HTML erhalten, indem Sie die CSR SPA-App ausführen:

document.getElementById('root').innerHTML

Vergessen Sie nicht, die einzigen Gründe für die Verwendung von SSR sollten sein:

  1. SEO
  2. Schnellere Ladungen (ich würde dies rabattieren)

Hack: https://medium.com/@gagan_goku/react-and-server-side-rendering-ssr-444d8c48abfc

Kira
quelle