3. diel - Serverové renderovanie s Next.js
V predchádzajúcej lekcii, Vykresľovanie v React a jeho optimalizácia , sme sa zoznámili s tým, ako v Reactu prebieha vykresľovanie. Popísali sme si stručne niektoré z možností ďalšej optimalizácie, konkrétne memoizáciu, lazy loading a virtualizáciu.
V dnešnom tutoriále pokročilého Reactu sa budeme zaoberať témou, ktorá sa stáva stále populárnejšou vo svete webových technológií – frameworkom Next.js a serverovým renderovaním (Server Side Rendering, skrátene SSR). Pri vývoji komplikovanejších webových aplikácií, pri ktorých je potrebné dáta spracovať ešte pred tým, než sa odošlú klientovi, sa totiž bez tejto techniky nezaobídeme.
Čo je Next.js?
Next.js je moderný React framework pre vývoj webových aplikácií. Je to veľmi silný nástroj, ktorý ponúka ako serverové renderovanie, tak aj statické stránkovanie. Framework je optimalizovaný pre maximálnu rýchlosť a bezpečnosť, a to zároveň s minimálnym konfiguračným úsilím. Teraz sa pozrime, ako s Next.s začať.
Aby sme mohli Next.js používať, potrebujeme Node.js na verziu aspoň 16.8.x. Ohľadom operačných systémov si nemusíme robiť starosti. Next.js ponúka plnú podporu pre Windows, macOS a Linux, či už pre samostatnú distribúciu, alebo WSL.
Vytvorenie Next.js projektu
Nový projekt vytvoríme jednoducho pomocou nasledujúcich príkazov.
Verzovací tag @latest
zaistí, že si nainštalujeme najnovšiu
verziu. Použitie príkazov v takejto forme nám zároveň stiahne aj React a
všetky potrebné závislosti:
Počas tvorby nového
projektu budeme v dialógu opýtaní na rad parametrov, typicky či chceme
používať JavaScript alebo TypeScript, pôvodný lokalizovaný
src/
adresár, CSS preprocesor atď. Pretože tvoríme iba malý
projekt, pri ktorom neoceníme typovú kontrolu, vystačíme si s JavaScriptom.
Tailwind na škodu určite nebude a úpravu formátovania cez ESLint určite
tiež oceníme. Natívne smerovanie Next.js určite tiež využijeme, ako si za
chvíľu ukážeme, a importovanie ponecháme pôvodné. Projekt sme si teda
nakonfigurovali nasledujúcim spôsobom:
Týmto sme vytvorili nový
Next.js projekt s názvom moje-aplikace
a spustili vývojový
server. Otvoríme webový prehliadač a zadáme adresu
http://localhost:3000/
. Uvítacia stránka Next.js bude vyzerať
podobne ako na nasledujúcom obrázku:
Serverové renderovanie pomocou Next.js
Keď už máme pripravený projekt, začneme so základmi serverového
renderovania. Next.js poskytuje funkciu getServerSideProps()
,
ktorú použijeme na načítanie dát na serverovej strane. Táto funkcia sa
spustí pri každej požiadavke a vráti props
(vlastnosti), ktoré
sa potom odovzdajú našej React komponentu. To teda znamená, že všetko, čo
si vo funkcii ďalej definujeme, bude vyvolané na serveri a nie vo webovom
prehliadači koncového klienta.
Predstavme si, že chceme v našej aplikácii zobraziť informácie o
filmových postavách zo Star Wars. Pretože kto by nechcel, aby jeho webová
aplikácia fungovala ako plnohodnotná Star Wars encyklopédia? Všetky tieto
informácie nemusíme sami manuálne dohľadávať, jednoducho ich získame z
verejného API na adrese https://swapi.dev/
.
Pokiaľ ešte v zložke src/
nevidíme podzložku
pages/
, vytvoríme si ju. Router Next.js v predvolenom nastavení
totiž automaticky generuje všetky nové stránky z JavaScriptových súborov
uložených v priečinku /src/pages/
. Pre nás to má výhodu v
tom, že nemusíme nič ďalšie manuálne konfigurovať. Ďalej si vytvoríme
náš vlastný komponent, ktorý nám postavy zo Star Wars vyrenderuje. Tú
potom implementujeme do novej stránky ako celok. Budeme tak ctiť ideológiu
Reactu, v ktorej by každá časť kódu plniaca špeciálnu funkciu mala byť
separovaná do svojej vlastnej, opakovane použiteľnej
komponenty.
Tvorba nového komponentu
Characters
Najprv vo vnútri zložky src/
vytvoríme novú zložku
components/
. Do nej budeme umiestňovať všetky naše komponenty.
Potom vo vnútri tohto priečinka vytvoríme nový súbor
Characters.js
.
Do súboru Characters.js
si naimportujeme knižnicu Reactu:
Ďalej si vytvoríme
komponent Characters
ako funkciu. Táto funkcia prijíma objekt
characters
ako prop
a vracia JSX kód, ktorý
zobrazuje informácie o každej postave zo Star Wars. Každá postava je
zobrazená vo svojom vlastnom <div>
elemente s názvom
postavy ako nadpisom a popisom ako odsekom. Zátvorky {}
sa
používajú na vyvolanie JavaScriptu priamo v HTML kóde (jedná sa o syntax
JSX). Takto môžeme priamo v HTML tagu pristupovať k jednotlivým hodnotám z
objektu characters
v každej iterácii:
V popise má každá postava uvedené koľko váži, aká je vysoká a aký má tón pleti. Toto všetko sme zistili z API Swapi, ktorého endpoint si môžeme sami prezrieť tu. Pretože sú dáta zo Swapi v angličtine, ilustratívne sme celý popis ponechali v rovnakom jazyku.
Kód sme nepísali pre každú postavu zvlášť, ale využili sme funkciu
map()
. Táto funkcia nám umožňuje vrátiť každý prvok z poľa
postáv, to znamená, že pre každú postavu bude vytvorený nový tag
<div>
.
Nakoniec exportujeme náš komponent Characters
ako
východiskový export:
Teraz je z
Characters
kompletný a opakovane použiteľný komponent. V
nasledujúcich kapitolách ju importujeme do stránky /postavy
, čo
bude ďalšia stránka našej webovej aplikácie, na ktorej užívateľ nájde
zoznam postáv zo Star Wars.
Implementácia stránky
/postavy
V našom podpriečinku pages/
vytvoríme nový súbor
postavy.js
a vložíme do neho nasledujúci kód. Najskôr si
naimportujeme knižnicu Reactu a tiež komponent Characters
:
Tento kód importuje
knižnicu React do nášho súboru. React je knižnica pre vývoj
používateľských rozhraní, ktorú budeme používať na vytváranie našej
stránky s postavami. Zaistí nám tiež, že budeme môcť jednoducho použiť
komponent Characters
.
Tvorba funkcie
CharactersPage()
Vytvoríme si novú funkciu CharactersPage()
, ktorú budeme
následne exportovať. Jedná sa o funkciu generujúcu celú novú stránku
postavy
. Implementujeme do nej komponent Characters
nasledujúcim spôsobom:
Vo funkcii
CharactersPage()
sme použili komponent Characters
a
priradili sme jej parameter characters
, čo je vstupný objekt s
postavami zo Star Wars. Je ukrytý v rovnomennej výstupnej premennej z funkcie
getServerSideProps()
, ktorej definíciu vykonáme nasledovne.
Definícia funkcie
getServerSideProps()
:
Funkcia getServerSideProps()
je špeciálna funkcia v Next.js,
ktorá sa spustí na serveri pred vykreslením stránky. Definujeme si ju
takto:
Táto funkcia získava dáta
pre našu stránku. V našom prípade funkcia sťahuje zoznam postáv zo Star
Wars z API na už spomínanej adrese. Výsledkom tejto funkcie je objekt s
vlastnosťou props
, ktorý obsahuje naše postavy. Tieto postavy
sú potom odovzdané do našej komponenty Characters
ako
prop
. V komponente Characters
definovanej vyššie
potom pristupujeme k jednotlivým vlastnostiam každej postavy.
Zaujímavá je funkcia fetch()
, ktorú sme použili na
načítanie dát. Táto funkcia je štandardnou súčasťou moderných webových
prehliadačov a umožňuje nám vykonať HTTP požiadavku. V našom prípade sme
ju použili na načítanie dát z API Star Wars. Dôležité je si uvedomiť,
že fetch je asynchrónna operácia, čo znamená, že môže
trvať nejaký čas, než sa dáta načítajú. Preto musíme použiť
kľúčové slovo await
, ktoré nám umožní počkať, až sa
dáta načítajú, než s nimi budeme ďalej pracovať.
Vo funkcii getServerSideProps()
sme tiež použili kľúčové
slovo async
, čo nám umožňuje používať await
vo
vnútri funkcie.
Exportovanie komponentu
CharactersPage
Nakoniec exportujeme náš komponent CharactersPage opäť ako východiskový export:
V React platí pravidlo, že
komponentom je technicky všetko. Routovanie v Next.js nám
však automatizovaným spôsobom umožňuje, že všetky komponenty vytvorené v
adresári pages/
sú považované za stránky.
Vďaka tomu vygeneruje Next.js stránku pre každý špecifický súbor v
spomínanom adresári. Takto sme komponent CharactersPage
použili
aj my. Implementovali sme do nej komponent Characters
, ktorý
slúži čisto na vykreslenie zoznamu s postavami.
Štylovanie v Tailwind CSS
Teraz máme API úspešne implementované a generovanie jeho obsahu na
stránke /postavy
úspešne dokončené. Overíme si to zadaním
URL stránky manuálne - http://localhost:3000/postavy
. Uvidíme
potom nasledujúci výstup:
Pokiaľ dostávame chybu 404, reštartujeme server.
Vidíme, že API funguje a že Next.s ho správne volá na serveri pred tým,
než nám do prehliadača vôbec pristane odpoveď. V rámci vizuálnej podoby
stránky by sme však mohli pridať nejaké vylepšenia:-) Poďme si vyskúšať
náš importovaný CSS preprocesor Tailwind. Next.js nám pri generovaní
počiatočnej šablóny už vytvoril konfiguračný súbor
tailwind.config.js
umiestnený v koreňovom adresári. V ňom je
nastavené, že sa štýly aplikujú na všetky súbory aj v adresároch
components/
a pages/
. Tailwind sa síce musí
dodatočne zavolať, to však generátor šablóny už aj zariadil. Konkrétne v
súbore app/globals.css
, kde sa Tailwind importuje. Nám teda
stačí v hornej časti súboru Characters.js
importovať
globals.css
nasledujúcim spôsobom:
K jednotlivým HTML tagom potom pridáme nasledujúce štýly, po ktorých aplikácii bude mať naša stránka aspoň nejaký vizuálny základ:
Zmeny v súbore
Characters.js
uložíme a pozrieme sa, ako náš zoznam postáv zo
Star Wars vyzerá po úprave:
Pridanie odkazu na hlavnú stránku
Teraz zostáva posledný krok, ktorým je prepojenie s titulnou stránkou.
Next.js, rovnako ako React, v tomto smere používa vlastný interný komponent
<Link />
, čo je optimalizovaná referencie pre interné
prelinkovanie.
Prejdime teda do súboru page.js
v priečinku
/src/app/
a naimportujme si komponent <Link />
z
Next.js nasledujúcim spôsobom:
Potom vložme do stránky za
tretí tag div
(<div className="relative flex place-items-center...
)
nasledujúci kód:
Tento kód vytvorí nový
odkaz s textom Star Wars postavy na titulnú stránku. Pri kliknutí na
text budeme premiestnení na stránku /postavy
. Pre jednoduchosť
sme kód vložili na vhodné miesto do inak nedotknutej titulnej stránky
Next.js, priamo pod hlavný obrázok s logom frameworku:
V prípade problému s knižnicou Link ju možno v kóde
nahradiť natívnym HTML odkazom
<a href="/postavy">Star Wars postavy</a>
.
Kedy sa oplatí serverové renderovanie?
V tutoriále sme sa dozvedeli o knižnici Next.js a preskúmali sme, ako
funguje serverové renderovanie. Prešli sme cez proces
vytvárania aplikácie a ukázali sme si, ako načítať dáta na serverovej
strane pomocou funkcie getServerSideProps()
.
Teraz sa pozrime na niektoré situácie, kedy uprednostníme použitie serverového renderovania a kedy je naopak vhodnejšie použiť renderovanie na strane klienta.
Serverové renderovanie
Serverové renderovanie uprednostníme pre:
- SEO citlivé stránky: Serverové renderovanie býva prospešné pre SEO, pretože vyhľadávače môžu ľahšie analyzovať a indexovať plne vykreslenú stránku prijatú zo servera.
- Stránky, ktoré potrebujú okamžite zobrazovať dynamické dáta: Ak naša stránka potrebuje zobrazovať dáta, ktoré sa často menia, a tieto dáta je potrebné užívateľovi zobraziť hneď po načítaní stránky, serverové renderovanie môže byť dobrou voľbou. Príkladom môže byť spravodajský web, ktorý potrebuje zobrazovať najnovšie články hneď po načítaní stránky.
- Zariadenia s nižším výkonom alebo pomalšie siete: Pretože stránka je plne vyrenderovaná na serveri, na strane klienta je vyžadované menej spracovania. To vedie k lepšiemu výkonu pre používateľov s menej výkonnými zariadeniami alebo pomalšími sieťovými podmienkami.
Klientske renderovanie uprednostníme pre:
- Vysoko interaktívne stránky: Klientske renderovanie bude prospešné pre stránky, ktoré vyžadujú veľa interakcie používateľa a nepotrebujú zobrazovať rôzne dáta hneď po každom načítaní stránky. Príkladom môže byť aplikácia, ktorá vyžaduje vstup používateľa predtým, než môže zobraziť akékoľvek užitočné dáta.
- Stránky, ktoré nie sú silne závislé na SEO: Ak naša stránka nemusí byť indexovaná vyhľadávačmi (napríklad užívateľský dashboard), je klientske renderovanie vhodnou voľbou.
- Menšia záťaž servera: Pri klientskom renderovaní server poskytuje iba statické súbory, čo znižuje jeho záťaž. Toto nadobúda na význame, pokiaľ prevádzkujeme aplikáciu s veľkým množstvom užívateľov.
V nasledujúcej lekcii, Hooky v React - useState(), useEffect() a useRef() , si bližšie si predstavíme hooky useState(), useEffect() a useRef().
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 28x (1.48 kB)
Aplikácia je vrátane zdrojových kódov v jazyku JavaScript