Jak implementovat vykreslování na straně serveru v aplikaci React ve třech jednoduchých krocích

Od Rohita Kumara

V tomto tutoriálu vytvoříme: pěknou kartu React, jako je tato.

V tomto tutoriálu použijeme vykreslování na straně serveru k doručení odpovědi HTML, když uživatel nebo crawler navštíví adresu URL stránky. Druhé požadavky budeme zpracovávat na straně klienta.

Proč to potřebujeme?

Nechte se vést k odpovědi.

Jaký je rozdíl mezi vykreslováním na straně klienta a vykreslováním na straně serveru?

Při vykreslování na straně klienta prohlížeč stáhne minimální stránku HTML. Vykresluje JavaScript a vyplňuje do něj obsah.

Při vykreslování na straně serveru se naopak vykreslují komponenty React na serveru. Výstupem je obsah HTML.

Tyto dva způsoby můžete kombinovat a vytvořit izomorfní aplikaci.

Nevýhody vykreslování Reactu na serveru

  • SSR může zlepšit výkon, pokud je vaše aplikace malá. Může ale také výkon zhoršit, pokud je těžká.
  • Zvyšuje dobu odezvy (a může být horší, pokud je server vytížený).
  • Zvyšuje velikost odezvy, což znamená, že načítání stránky trvá déle.
  • Zvyšuje složitost aplikace.

Kdy byste měli použít vykreslování na straně serveru?

I přes tyto důsledky SSR existují situace, kdy jej můžete a měli byste použít.

SEO

Každý web se chce zobrazovat ve vyhledávání. Opravte mě, pokud se mýlím.

Naneštěstí vyhledávače zatím nerozumí/nevykreslují JavaScript.

To znamená, že vidí prázdnou stránku bez ohledu na to, jak užitečný váš web je.

Mnozí lidé tvrdí, že vyhledávač Google nyní vykresluje JavaScript.

Abych to otestoval, nasadil jsem aplikaci na Heroku. Zde je to, co jsem viděl v konzole Google Search Console:

Prohlížeč Google nerenderuje React

Prázdná stránka.

To byl největší důvod, proč jsem prozkoumal vykreslování na straně serveru. Zvláště když se jedná o stěžejní stránku, jako je vstupní stránka, blog a podobně.

Chcete-li ověřit, zda Google vykresluje váš web, navštivte:

Panel nástrojů konzoly vyhledávání > Procházet > Načtení jako Google. Zadejte adresu URL stránky nebo ji nechte prázdnou pro domovskou stránku.

Zvolte možnost FETCH AND RENDER. Po dokončení kliknutím zobrazte výsledek.

Zlepšení výkonu

V SSR závisí výkon aplikace na prostředcích serveru a rychlosti sítě uživatele. Díky tomu je velmi užitečný pro weby náročné na obsah.

Příklad: Řekněme, že máte středně drahý mobilní telefon s pomalou rychlostí internetu. Zkusíte vstoupit na web, který stahuje 4 MB dat, než se vám cokoli zobrazí.

Byli byste schopni zobrazit cokoli na obrazovce během 2-4 sekund?

Navštívili byste tento web znovu?

Myslím, že ne.

Dalším významným zlepšením je doba první interakce uživatele. Jedná se o rozdíl v čase od okamžiku, kdy uživatel narazí na adresu URL, do okamžiku, kdy se mu zobrazí obsah.

Tady je srovnání. Testoval jsem to na vývojovém počítači Mac.

Reakce vykreslená na serveru

Zpráva o výkonu SSR (Chrome)

Čas první interakce je 300ms. Hydratace skončí za 400ms. Událost načítání končí přibližně za 500ms. Můžete se o tom přesvědčit, když se podíváte na obrázek výše.

Reakce vykreslená v prohlížeči klienta

Report výkonu na straně klienta (Chrome)

Čas první interakce je 400ms. Událost načtení končí v čase 470ms.

Výsledek hovoří sám za sebe. U tak malé aplikace je rozdíl v době první interakce s uživatelem 100 ms.

Jak to funguje? – (4 jednoduché kroky)

  • Vytvořte čerstvý Redux Store při každém požadavku.
  • Případně odešlete nějaké akce.
  • Získejte stav ze Store a proveďte SSR.
  • Odešlete stav získaný v předchozím kroku spolu s odpovědí.

Stav předaný v odpovědi použijeme pro vytvoření počátečního stavu na straně klienta.

Než začnete, naklonujte/stáhněte si kompletní příklad z Githubu a použijte ho jako referenci.

Začínáme nastavením naší aplikace

Nejprve otevřete svůj oblíbený editor a shell. Vytvořte novou složku pro vaši aplikaci. Začněme.

npm init --yes

Vyplňte údaje. Po vytvoření package.json do ní zkopírujte níže uvedené závislosti a skripty.

Nastavte všechny závislosti spuštěním:

npm install

Pro fungování našeho sestavovacího skriptu je třeba nakonfigurovat Babel a Webpack.

Babel transformuje ESM a react do kódu srozumitelného pro Node a prohlížeč.

Vytvořte nový soubor .babelrc a vložte do něj níže uvedený řádek.

{ "presets": }

webpack spojí naši aplikaci a její závislosti do jednoho souboru. Vytvořte další soubor webpack.config.js s následujícím kódem:

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

Výstupem procesu sestavení jsou dva soubory:

  1. assets/bundle.js – čistě klientská aplikace.
  2. assets/client.js – klientský společník pro SSR.

Složka src/ obsahuje zdrojový kód. Zkompilované soubory Babel patří do views/. Adresář views se vytvoří automaticky, pokud není přítomen.

Proč potřebujeme kompilovat zdrojové soubory?

Důvodem je rozdíl v syntaxi mezi ESM & CommonJS. Při psaní Reactu a Reduxu hojně používáme import a export ve všech souborech.

Naneštěstí v Node nefungují. Zde přichází na pomoc Babel. Níže uvedený skript řekne Babelu, aby zkompiloval všechny soubory v adresáři src a výsledek umístil do adresáře views.

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

Nyní je může Node spustit.

Kopírování předpřipravených & Statických souborů

Pokud jste již naklonovali úložiště, kopírujte z něj. V opačném případě si stáhněte soubor ssr-static.zip ze služby Dropbox. Rozbalte jej a tyto tři složky ponechte uvnitř adresáře aplikace. Zde je uvedeno, co obsahují:

  1. Reakce App a komponenty se nachází ve složce src/components.
  2. Soubory Redux ve složce src/redux/.
  3. assets/ & media/:

Server Side

Vytvořte dva nové soubory s názvy server.js a template.js uvnitř složky src/.

src/server.js

Kouzla se dějí zde. Toto je kód, který jste hledali.

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

Místo vykreslování naší aplikace ji musíme zabalit do funkce a exportovat. Funkce přijme počáteční stav aplikace.

Takto to funguje.

  1. Předejte initialState do configureStore(). configureStore()vrátí novou instanci úložiště. Držte ji uvnitř proměnné store.
  2. Vyvolejte metodu renderToString() a jako vstup zadejte naši aplikaci. Ta vykreslí naši aplikaci na serveru a vrátí vytvořené HTML. Nyní proměnná content uchovává HTML.
  3. Získejte stav z Redux Store voláním getState() na store. Uchovejte jej v proměnné preloadedState.
  4. Vraťte stav content a preloadedState. Ty předáme naší šabloně, abychom získali výslednou stránku HTML.

2. src/template.js

template.js exportuje funkci. Jako vstupy přijímá title, state a content. Vloží je do šablony a vrátí výsledný dokument HTML.

Pro předání stavu šablona připojí state k window.__STATE__ uvnitř značky <script>.

Nyní lze state číst na straně klienta přístupem k window.__STATE__.

V další značce skriptu také zahrneme doprovodnou aplikaci SSR assets/client.js na straně klienta.

Pokud si vyžádáte čistě klientskou verzi, vloží se pouze assets/bundle.js dovnitř značky skriptu.

Klientská strana

Klientská strana je poměrně jednoduchá.

src/bundle.js

Takto se zapíše obal React a Redux Provider. Je to naše čistá aplikace na straně klienta. Žádné triky tu nejsou.

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

Připadá vám to povědomé? Ano, není na tom nic zvláštního kromě window.__STATE__. Jediné, co musíme udělat, je vzít počáteční stav z window.__STATE__ a předat ho naší funkci configureStore() jako počáteční stav.

Podívejme se na náš nový klientský soubor:

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

Podívejme se na změny:

  1. Vyměňte render() za hydrate(). Soubor hydrate() je stejný jako render(), ale používá se k hydrataci prvků vykreslených pomocí ReactDOMServer. Zajišťuje, že obsah je stejný na serveru i na klientovi.
  2. Přečti stav z globálního objektu okna window.__STATE__. Uložte jej do proměnné a window.__STATE__ smažte.
  3. Vytvořte nové úložiště s state jako initialState.

Vše je hotovo.

Složení všeho dohromady

Index.js

Toto je vstupní bod naší aplikace. Zpracovává požadavky a šablonování.

Také deklaruje proměnnou initialState. Vymodeloval jsem ji pomocí dat v souboru assets/data.json . Předáme ji naší funkci ssr().

Poznámka: Při odkazování na soubor, který je uvnitř src/, ze souboru mimo src/ , použijte normální require() a src/ nahraďte views/. Důvod znáte (kompilace Babelu).

Routing

  1. /: Ve výchozím nastavení serverem renderovaná domovská stránka.
  2. /client:
  3. /exit: Tlačítko pro zastavení serveru. Dostupné pouze při vývoji.

Build & Run

Nastal čas sestavit a spustit naši aplikaci. Můžeme to udělat pomocí jediného řádku kódu.

npm run build && npm run start

Nyní aplikace běží na http://localhost:3000.

Jste připraveni stát se React Pro?

Od příštího pondělí začínám nový seriál, díky kterému se vaše dovednosti v Reactu okamžitě rozzáří.

odkaz na přihlášení níže ?

Děkuji, že jste si to přečetli.

Pokud se vám to líbí a přijde vám to užitečné, sledujte mě na Twitteru & Webflow.

.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.