Znalostní wiki OKF
Část 3 · Postav to a doruč

Statické, dynamické a hybridní weby

'Statický vs. dynamický' je falešná dvojice. Skutečná otázka zní, kdy vzniká HTML: při buildu, na serveru při požadavku, nebo až v prohlížeči.


Tým staví nový obsahový web a zvolí SPA, „protože je to moderní". Stránka se v prohlížeči poskládá z JavaScriptu krásně. Pak přijde Googlebot, stáhne HTML a najde prázdný shell. Reálný obsah je schovaný za JS, který se má teprve spustit. Web je technicky online, ale ve výsledcích vyhledávání skoro neexistuje.

A nestalo se to malé firmě. V květnu 2020 dostala chyba v JS na Hulu Googlebota do stavu, kdy crawler dostával 404 tam, kde uživatel viděl HTTP 200. Za pár týdnů spadla viditelnost ve vyhledávání o 56 %, 64 % obsahu vracelo při crawlu 404, postiženy byly desetitisíce stránek seriálů a filmů. Trvalo to skoro tři týdny. Učebnicový případ, proč rozhodnutí o renderingu není kosmetika.

A přitom celý ten zmatek pramení z jedné špatné otázky. Lidé se ptají „bude web statický, nebo dynamický?", jako by to byly dva druhy webu. Nejsou. Rendering je okamžik, kdy vznikne výsledné HTML, a ten okamžik leží na ose. Jednovětou definici má společný slovník, tahle kapitola tu osu rozebírá a říká, kdy zvolit které místo na ní.

Tři místa, kde se rodí HTML

HTML může vzniknout na třech místech. Každé za něco platí a něco vrací.

Při buildu (SSG, Static Site Generation). HTML se vygeneruje jednou, při sestavení webu, uloží jako soubory a doručuje z CDN. Žádný výpočet pro jednotlivého uživatele, žádný server, který by mohl spadnout pod náporem. Načtení je extrémně rychlé, hosting levný a jednoduchý, crawler vidí reálný obsah okamžitě. Ideál pro marketing, blogy a dokumentaci. Tedy obsah, který je pro všechny stejný a nemění se každou vteřinu.

Na serveru při požadavku (SSR, Server-Side Rendering). HTML se vykreslí znovu při každém příchodu uživatele. Hodí se na čerstvý nebo personalizovaný obsah: e-shop s aktuální cenou a skladovostí, stránka, která ví, kdo je přihlášený. Cena je serverový runtime, vyšší latence a nutnost škálovat výpočet podle návštěvnosti.

V prohlížeči (CSR, Client-Side Rendering). Prohlížeč dostane minimální HTML a velký balík JavaScriptu, ten stáhne, spustí, stáhne si data a teprve pak postaví DOM. To je svět SPA. Dává smysl pro přihlášené dashboardy a vysoce interaktivní aplikace, kde je pomalejší první načtení přijatelná daň za aplikační zážitek. Pro veřejný obsahový web je to past. Přesně ta z Hulu.

Mezi „statický" a „dynamický" tedy nevede ostrá čára. Vede po ní spojité spektrum podle toho, jak pozdě se HTML poskládá. Čím dřív, tím rychleji a levněji se doručí, ale tím starší může být. Čím později, tím čerstvější a osobnější, zato dražší a křehčí.

Proč čistý CSR škodí nalezitelnosti

Googlebot nezpracovává JavaScript v jednom kroku. Indexuje ve dvou vlnách: nejdřív stáhne syrové HTML, a teprve v druhé vlně ho pošle do Web Rendering Service, který stránku vykreslí v headless Chromiu. Mezi vlnami je zpoždění. Hodiny, dny, klidně týdny. Druhá vlna se řídí důležitostí webu, crawl budgetem a dostupností zdrojů. Pojem se proto posouvá od „crawl budget" k „render budget". Nejde jen o to, kolik stránek Google stáhne, ale kolik jich je ochotný vykreslit.

Pro statickou stránku je to jedno. Obsah je v HTML hned, první vlna ho vidí celý. Pro čistý CSR to znamená, že obsah čeká na nejistou druhou vlnu, a u velkého webu s desetitisíci často měnících se stránek nemusí přijít včas, nebo vůbec. Proto je čistý CSR riziko všude, kde má obsah hodnotu jen čerstvý, kde přichází hlavní návštěvnost z organického vyhledávání, nebo kde klíčový obsah existuje výhradně v JS. Detail dopadu na vyhledávání řeší SEO.

Tím padá nejodolnější mýtus v oboru: „dynamický web je lepší pro SEO." Je to obráceně. SSG dává crawlerovi reálné HTML okamžitě a bez podmínek. Dynamika v podobě client-side renderingu nalezitelnosti spíš škodí.

Hybrid: pro každou stránku, ne pro celý web

Tady se ukazuje, proč je původní otázka špatná. Moderní frameworky jako Next.js a Astro nenutí volit jeden režim pro celý web. Volíte ho pro každou stránku zvlášť. Landing page a blog předgenerujete staticky, košík renderujete na serveru, přihlášený účet necháte na klientovi. Jeden web, tři strategie. „Statický web vs. dynamický web" je falešná dvojice právě proto, že reálně se míchá.

Dva vzory stojí za zmínku. Ukazují totiž, že hybrid není kompromis, ale způsob, jak mít rychlost statiky i čerstvost zároveň.

ISR (Incremental Static Regeneration) od Next.js řeší starý spor mezi „rychlé, ale zastarává" a „čerstvé, ale drahé". Stránka je předgenerovaná při buildu a doručovaná z CDN jako statika, ale umí se revalidovat i po deployi — buď po časovém okně, nebo na vyžádání. Model je stale-while-revalidate: doručuje se cachovaná verze, na pozadí se regeneruje, když zestará. Revalidace na vyžádání přišla v Next.js 12.2.0 a nejodolnější vzor kombinuje obojí. Webhook z CMS při publikaci aktualizuje stránku okamžitě, a časové okno je záchranná síť pro případ, že webhook selže. (Pozor: ISR potřebuje Node.js runtime, u čistého statického exportu nefunguje.)

Islands architecture (Astro, partial hydration) útočí na druhou stranu problému, na JavaScript. Server vykreslí stránku jako statické HTML a kolem dynamických částí nechá „ostrovy", které se na klientu hydratují samostatně. Zbytek stránky zůstane statické HTML bez JS. To dramaticky zmenší objem kódu, který musí prohlížeč stáhnout a spustit. Astro řídí hydrataci direktivami jako client:idle, client:visible nebo client:media, takže ostrov ožije až ve chvíli, kdy je opravdu potřeba. Existují i server islands, fragment renderovaný na serveru zvlášť od zbytku statické stránky.

Menší objem JS se přímo propisuje do výkonu: reálné HTML hned je dobré LCP, méně JS je lepší interaktivita i méně posunů layoutu. Islands a partial hydration jsou nástroj, jak tohle získat, aniž byste obětovali statiku.

Tahle linie má historii. SPA boom přinesl aplikační komfort, ale i SEO bolest. Odpovědí byl isomorphic rendering a SSR, pak Jamstack a návrat ke statice. Termín Jamstack (JavaScript, API, Markup) zavedl Mathias Biilmann z Netlify v roce 2015: oddělit prezentaci od dat, předrenderovat markup a doručovat z edge, interaktivitu řešit klientským JS, dynamiku přes API. ISR a islands jsou poslední krok toho oblouku. Statika jako základ, dynamika jen tam, kde ji obsah potřebuje.

Statické neznamená bez CMS

Druhý mýtus, který je potřeba zabít: „statický web = bez CMS, nejde do něj editovat." Není pravda. Statické znamená jen to, že HTML vznikne předem při buildu. CMS běží úplně normálně, editor píše, schvaluje, publikuje. Jen se na obsah sahá v jiném okamžiku: změna v CMS nespustí nové renderování při návštěvě, ale spouštěč buildu nebo webhook, který přegeneruje dotčené stránky. Headless CMS nad SSG je dnes standard.

Tady se renderování potkává s content modelem. Strukturovaná entita — článek s polem titulek, autor, tělo — je vstupem do renderování. Renderování je krok, který tu entitu mění na HTML, ať při buildu, na serveru, nebo na klientovi. Co se modeluje jako data, jde vykreslit libovolnou strategií.

A protože renderování bývá krok buildu, je to zároveň krok CI/CD pipeline. Tady začíná být build-time cena reálná. O tom je další oddíl.

Rozhodovací rámec

Místo „statický, nebo dynamický?" se ptejte čtyři otázky a poskládejte odpověď pro každou stránku.

Volba renderingu určuje hosting

Rendering není čistě technický detail. Rozhodujete tím o nákladech, riziku i nalezitelnosti najednou. A nejviditelněji se to promítne do hostingu.

Čistě statický web utáhne triviální hosting. GitHub Pages dá web do 1 GB, měkký limit 100 GB přenosů měsíčně a 10 buildů za hodinu, a žádný serverový runtime — což zároveň znamená, že SSR ani ISR tam nerozjedete. Jakmile zvolíte SSR nebo ISR, potřebujete serverový nebo edge runtime a výpočet na originu. Renderování tedy rozhoduje, jaký hosting vůbec přichází v úvahu. Proto se tahle volba dělá dřív než výběr hostingu, ne naopak.

Tři typické záměny

Číst plnou verzi ve wiki →

11 / 26