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?
- Nevýhody vykreslování Reactu na serveru
- Kdy byste měli použít vykreslování na straně serveru?
- SEO
- Zlepšení výkonu
- Reakce vykreslená na serveru
- Reakce vykreslená v prohlížeči klienta
- Jak to funguje? – (4 jednoduché kroky)
- Začínáme nastavením naší aplikace
- Proč potřebujeme kompilovat zdrojové soubory?
- Kopírování předpřipravených & Statických souborů
- Server Side
- src/server.js
- 2. src/template.js
- Klientská strana
- src/bundle.js
- src/client.js
- Složení všeho dohromady
- Index.js
- Build & Run
- Jste připraveni stát se React Pro?
- Děkuji, že jste si to přečetli.
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:
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
Č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
Č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:
-
assets/bundle.js
– čistě klientská aplikace. -
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í:
- Reakce
App
a komponenty se nachází ve složcesrc/components
. - Soubory Redux ve složce
src/redux/
. -
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.
- Předejte
initialState
doconfigureStore()
.configureStore()
vrátí novou instanci úložiště. Držte ji uvnitř proměnnéstore
. - 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. - Získejte stav z Redux Store voláním
getState()
nastore
. Uchovejte jej v proměnnépreloadedState
. - Vraťte stav
content
apreloadedState
. 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 <scri
pt>.
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:
- Vyměňte
render()
zahydrate()
. Souborhydrate()
je stejný jakorender()
, ale používá se k hydrataci prvků vykreslených pomocíReactDOMServer
. Zajišťuje, že obsah je stejný na serveru i na klientovi. - Přečti stav z globálního objektu okna
window.__STATE__
. Uložte jej do proměnné awindow.__STATE__
smažte. - 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
-
/
: Ve výchozím nastavení serverem renderovaná domovská stránka. -
/client
: -
/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áří.
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.
.