IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

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:

Hlavná stránka nového Next.js projektu - Pokročilý React

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

Postavy zo Star Wars - Pokročilý React

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:

Star Wars postavy s vizuálnou úpravou - Pokročilý React

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:

Titulná strana Next.s s odkazom na stránku s postavami - Pokročilý React

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

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 mnohých moderných webových aplikáciách nachádzame kombináciu oboch - serverového aj klientskeho renderovania. Toto sa niekedy označuje ako univerzálne alebo aj izomorfné renderovanie. Serverové renderovanie použijeme na rýchle servírovanie kostry našej aplikácie a nejakých počiatočných dát a klientske renderovanie ďalej pre následné interakcie užívateľa a aktualizácie dát. Next.js je pre tento druh hybridného prístupu vynikajúcim frameworkom.

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é 27x (1.48 kB)
Aplikácia je vrátane zdrojových kódov v jazyku JavaScript

 

Predchádzajúci článok
Vykresľovanie v React a jeho optimalizácia
Všetky články v sekcii
Pokročilý React
Preskočiť článok
(neodporúčame)
Hooky v React - useState(), useEffect() a useRef()
Článok pre vás napísal Matouš Vondrák
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Aktivity