cesko-digital / app

Komunitní aplikace Česko.Digital

Home Page:https://app.cesko.digital

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Opravit kešování stránek

zoul opened this issue · comments

Některé stránky nám evidentně nezůstávají v keši, například projektové stránky nebo hledané role nebo akce. Když klikám po aplikaci, tak se po úvodní prodlevě načítají rychle, ale to podle mě není keš na CDN, protože opětovné načtení té stránky ze stejného URL zase trvá – a to by nemělo.

(Dřív jsme generovali maximum věcí staticky, ale to hodně prodlužuje build. Obecně bychom raději nechali ty stránky dynamické, ale s tím, že se pak budou kešovat aspoň pár minut na CDN.)

Koukám do logů a přijde mně, že se nekešuje čtení z Airtable, takže je pak celá stránka „věčně živá“. (To logování odchozích požadavků je hodně beta, ignoroval bych ho.)

V app directory mas defaultni cache tusim 30s (porad to meni) a muzes si ji nastavit podle sebe magickymi exporty. Stejne tak si muzes nastavit cachovani Airtable requestu, ale to neni treba resit. Staci nastavit zivotnost cache jednotlivych stranek na neco rozumneho, treba 10 min.

Já už jsem z toho právě úplně tumpachový – všude jsem nasázel export const revalidate = 300 a očekával bych, že tím pádem budou stránky pět minut kešované na CDN. Nejsou, v logu furt vidím, že když požádám například o /projects/[slug], tak to pár sekund trvá a v logu vidím, že se provedla odpovídající funkce.

Ja nerikam, ze tomu celemu cache stacku dokonale rozumim. Ale po nejakem boji jsem se na vice projektech dostal na fungujici variantu.

Zkus si to otestovat generovanim random cisla/uuid v te page a vypisovani. Behem refreshu by se nemela menit a zmenit se jednou za 5 min.

Muzu na to zitra kouknout, kde je jake nastaveni.

Díky moc! To kešování je pro mě momentálně nejbolestivější část Nextu + Vercelu, je tam hrozně moc proměnných, chová se to jinak na lokálu a jinak na produkci a celkově je to labyrint. Na co jsem zatím dál přišel:

  • Funguje to správně pro „statické“ stránky a la /projects. Ty se načítají okamžitě a v logu k nim naskočí záznam jednou za revalidate sekund. Tohle je klasický režim inkrementálního statického renderování (ISR). Rozumím, očekávám, miluju.
  • Očekával bych, že se zhruba totéž bude dít pro dynamické stránky a la /projects/[slug]. Tedy že první dotaz stránku renderuje, uloží na CDN (v prohlížeči patrné zpoždění) a následné dotazy až do revalidate sekund nebudou vůbec vidět v logu (CDN hit) a načtou se v prohlížeči okamžitě. Což se neděje, vidím pokaždé nový render na serveru. Nerozumím, neočekávám, hejtím.

Vrátím se k tomu zítra ráno, dneska už bych to rozmlátil :) A odložím si sem dva odkazy: diskuze o kešování dynamických rout, deep dive o kešování (doufám, že na tohle nebude muset dojít :)

OK, jako poslední pokus jsem v aecb6c9 přidal do projects/[slug]/page.tsx tohle:

export async function generateStaticParams() {
  return [];
}

Teď je ta routa označená jako SSG (černé kolečko) namísto dynamické (lambda) a funguje to tak, jak si představuju. Akorát nevím, jestli nejsme zpátky v tom režimu, že to celé generuje předem 🙈 Dořeším zítra.

Je to tak, tenhle dummy import mění situaci. Říkat tomu static site generation (SSG) je pro mě trochu matoucí, ale funguje to správně – počet stránek generovaných předem neroste, build zůstává rychlý, při prvním načtení stránky je furt vidět prodleva, ale další načtení už jsou okamžité (CDN hit) a v logu nevidím buď nic, anebo různé varianty na cache hit. Teď ještě aby se to opravdu měnilo po revalidate sekundách, ale tomu už věřím.

V praxi by stejně ještě bylo dobré dodělat loading varianty pro běžně používané typy stránek (projekty, role, akce, …), protože to „zaseknutí“ není vůbec pěkné UX (založím ticket).

Ještě jednou projdu všechny routy a ujasním si, jestli mají to kešování nastavené správně, pak tohle zavřu.

Tak jsem do toho zabrousil a to jsem nemel delat. Ted uz z toho nejspis nevybrousim. Ale v zasade se zda, ze Next se rozhoduje nad "defaultem" podle toho, jestli nekde ve strome (kompletnich importech) se nachazi nejaka funkce, co povazuje za dynamickou. Pokud ano, tak defaultuje do lambdy (λ), pokud ne, tak defaultuje do ISR (○).

Jednoduchy test v Page() statickeho obsahu:

  const result = await fetch("https://google.com");
  const header = headers().get("content-type");

Takhle vybuildi λ. Se zakomentovanym // const header = headers().get("content-type"); vybuildi ○. Podle vseho jsou podezreli: headers(), cookies() a useSearchParams().

Da se to overridnout magickymi exporty (tak, jak to delas), ale bal bych se tam side-effectu.

Jáj! Díky. Z toho teda nemám radost, že nějaká změna uvnitř celého stromu může změnit typ stránky. Už je to pro mě moc action at a distance, byl bych radši, kdyby to bylo explicitnější. Extra u toho kešování, které se blbě testuje.

Z toho řešení přes generateStaticParams vůbec nemám radost, je to nesmyslný kus kódu použitý jen ke změně infra. Byl bych mnohem radši, kdybych mohl tyhle věci někde nastavit explicitně. (Klidně s tím, že jako výchozí chování by zůstala ta autodetekce.)