spinny:~/writing $ less nextjs-16-cache-components.md
12Po léta jedna z nejotravnějších otázek v Next.js zní: „Je tato stránka statická nebo dynamická?“. Zdá se to jako jednoduchá otázka, dokud nepřidáte volání `cookies()`, `fetch` s různými možnostmi, databázového klienta, CMS, nákupní košík nebo vlastní obsah.34Next.js 16 je zajímavý, protože se snaží tuto konverzaci učinit méně tajemnou. Neodstraňuje složitost, ale posouvá mentální model: trasy jsou ve výchozím nastavení dynamické, mezipaměť se deklaruje tam, kde je potřeba, a `Suspense` se stává přirozeným způsobem, jak skládat rychlé skořápky s částmi, které zůstávají čerstvé.56Funkce, kterou je třeba pochopit, jsou komponenty mezipaměti. Stable Turbopack, React Compiler, `proxy.ts` a nová rozhraní API pro zneplatnění jsou důležité, ale točí se kolem stejného problému: vytváření rychlých aplikací, aniž byste museli hádat, jak se framework v zákulisí rozhodl.78## Protože na této věci záleží910Ve skutečné aplikaci nemáte jen „statické stránky“ a „dynamické stránky“. Máte různé kousky s různými potřebami.1112Produktový list se může několikrát denně změnit. Cena se může měnit častěji. Dostupnost musí být téměř živá. Uživatelské jméno je osobní. Recenze lze streamovat. Boční lišta může být stabilní. Vozík ne.1314Pokud se vším zacházíte jako s jednou jednotkou, vždy skončíte v jednom ze dvou extrémů:1516- agresivní ukládání do mezipaměti a riziko zobrazení starých dat;17- dynamické vykreslování všude a výkon horší, než je nutné.1819Komponenty mezipaměti slouží právě k tomu, aby se zabránilo této falešné volbě.2021## Model v praxi2223Pomocí `cacheComponents: true` můžete deklarovat, co je možné uložit do mezipaměti pomocí `"use cache"`. Poté můžete přiřadit trvání a značky k `cacheLife()` a `cacheTag()`. Dynamické části zůstávají dynamické a lze je izolovat pomocí `Suspense`.2425```mermaid26flowchart TD27 Request[Žádost uživatele] --> Shell[Skořápka uložená v mezipaměti]28 Request --> Dynamic[Dynamické sekce]29 Shell --> FirstPaint[První rychlý obsah]30 Dynamic --> Stream[Streamování v Suspense]31 Stream --> Complete[Celá stránka]32```3334Nastavení je malé:3536```typescript37// next.config.ts38import type { NextConfig } from 'next';3940const nextConfig: NextConfig = {41 cacheComponents: true,42};4344export default nextConfig;45```4647Velká změna není v konfiguraci. Jde o to, jak začnete psát komponenty.4849```tsx50// app/products/[slug]/page.tsx51import { Suspense } from 'react';52import { cacheLife, cacheTag } from 'next/cache';5354async function getProduct(slug: string) {55 'use cache';5657 cacheLife('hours');58 cacheTag(`product:${slug}`);5960 return db.product.findUnique({ where: { slug } });61}6263async function ProductDetails({ slug }: { slug: string }) {64 const product = await getProduct(slug);6566 return (67 <section>68 <h1>{product.name}</h1>69 <p>{product.description}</p>70 </section>71 );72}7374async function LiveInventory({ slug }: { slug: string }) {75 const inventory = await db.inventory.findFirst({ where: { slug } });76 return <p>{inventory.quantity} pezzi disponibili</p>;77}7879export default async function ProductPage({ params }: { params: Promise<{ slug: string }> }) {80 const { slug } = await params;8182 return (83 <>84 <ProductDetails slug={slug} />85 <Suspense fallback={<p>Controllo disponibilità...</p>}>86 <LiveInventory slug={slug} />87 </Suspense>88 </>89 );90}91```9293Stránka nemusí být celá uložena v mezipaměti nebo musí být dynamická. Produktový list může být rychlý a opakovaně použitelný. Zásoby mohou zůstat čerstvé. Uživatel něco vidí hned, aniž by čekal na nejpomalejší část.9495## `use cache` je spustitelná dokumentace9697Na `"use cache"` se mi líbí to, že vás nutí vyjádřit záměr. Když čtete funkci, okamžitě pochopíte, že se někdo rozhodl: „tato data lze znovu použít“.9899Je to zvláště užitečné, když nepoužíváte `fetch`. Mnoho aplikací čte data z Prisma, Drizzle, interních SDK, CMS klientů nebo servisních funkcí. V těchto případech staré úvahy založené pouze na možnostech `fetch` nestačily.100101Základní pravidlo:102103- obsah cachea relativně stabilní;104- používat granulované značky;105- opustí dynamická oprávnění, relace, košíky, oznámení a transakční stavy;106- vložte pomalé části dovnitř `Suspense`;107- změřte, než řeknete „zlepšili jsme výkon“.108109## Zneplatnit, aniž byste všechno zahodili110111Mezipaměť je užitečná pouze tehdy, pokud ji dokážete přesně aktualizovat. Zde se stávají důležitými `cacheTag`, `revalidateTag` a `updateTag`.112113Příklad:114115```typescript116'use server';117118import { updateTag } from 'next/cache';119120export async function updateProductName(productId: string, name: string) {121 await db.product.update({122 where: { id: productId },123 data: { name },124 });125126 updateTag(`product:${productId}`);127}128```129130Důležitým detailem je štítek. `product:${productId}` uvádí přesnou hranici. `products` říká obrovské vědro. Zpočátku je obrovský kbelík pohodlný; po několika měsících se to stane důvodem, proč zrušíte platnost poloviny aplikace, abyste změnili název.131132## Stabilní Turbopack: součást, kterou slyšíte každý den133134Next.js 16 přináší Turbopack do centra pro vývoj a sestavení. Není to nejpoetičtější funkce, ale je to ta, kterou cítíte při práci: server, který se spouští dříve, rychleji se obnovuje, sestavy, které vám přestanou připadat jako nucená přestávka na kávu.135136To znamená, že bych nemigroval kódovou základnu plnou vlastních pluginů se zavřenýma očima. Zkontroloval bych:137138- místní stavba;139- nestandardní dovoz;140- MDX, SVG a CSS;141- Webpack pluginy vlevo;142- kritické stránky;143- rozdíly v dobách výstavby.144145U nových projektů bych začal od výchozího nastavení. U zralých bych udělal měřenou migraci.146147## React Compiler: odstraňte šum, ne myšlenku148149React Compiler 1.0 je stabilní a Next.js 16 jej podporuje s `reactCompiler`. Slibem je snížit množství ručního zapamatování: méně `memo`, méně `useMemo`, méně `useCallback` používané „pro bezpečnost“.150151```typescript152// next.config.ts153import type { NextConfig } from 'next';154155const nextConfig: NextConfig = {156 reactCompiler: true,157};158159export default nextConfig;160```161162Nechoval bych to jako kouzelný prach. Kompilátor pomáhá, když kód dobře dodržuje pravidla React. Pokud mají komponenty podivné vedlejší účinky, skryté mutace nebo špatně použité háčky, je třeba to nejprve opravit.163164Zdravý způsob, jak to vyzkoušet:1651661. aktualizovat `eslint-plugin-react-hooks`;1672. opravit skutečná porušení;1683. povolit jej v kontrolované oblasti;1694. měřit dobu výstavby a chování;1705. ruční ukládání do paměti odstraňte pouze tehdy, když již není potřeba.171172Cílem není vymazat každých `useMemo`. Cílem je přestat psát preventivní zapamatování, protože se bojíme vykreslování.173174## `proxy.ts` a hranici sítě175176Ze starého `middleware.ts` se stane `proxy.ts`. Jde o změnu názvu, ale dává to smysl: tento soubor leží na hranici požadavku, není to tradiční generický middleware typu backend.177178```typescript179// proxy.ts180import { NextRequest, NextResponse } from 'next/server';181182export default function proxy(request: NextRequest) {183 const isLoggedIn = Boolean(request.cookies.get('session'));184185 if (!isLoggedIn && request.nextUrl.pathname.startsWith('/dashboard')) {186 return NextResponse.redirect(new URL('/login', request.url));187 }188189 return NextResponse.next();190}191```192193Pravidlo je zde jednoduché: držte to malé. Přesměrování, auth routing, hlavičky, zásadní přepisy. Pokud vám to začne připadat jako druhý backend, pravděpodobně toho dělá příliš mnoho.194195## Jak bych opravdu migroval196197Nezapínal bych všechny funkce najednou. udělal bych toto:1981991. Aktualizuji Next, React a React DOM;2002. Spouštím oficiální codemod;2013. Opravuji zásadní změny na `params`, `searchParams`, `cookies()`, `headers()` a `draftMode()`;2024. Migruji `middleware.ts` na `proxy.ts`;2035. Kontroluji sestavení a kritické stránky;2046. Povoluji komponenty mezipaměti v sekci, kde mezipaměť aktuálně vytváří tření;2057. Definuji konvence pro značky a zneplatnění;2068. Zkouším React Compiler samostatně;2079. srovnání metrik před a po.208209Dobrá migrace není ta, která využívá všechny nové funkce. Díky tomu je chování aplikace čitelnější.210211## Co se mění ve způsobu myšlení212213Na Next.js 16 je nejužitečnější to, že vás nutí lépe pojmenovávat záměry. Funkce není jen „získat produkt z databáze“. Je to "získat produkt, můžu ho hodiny uložit do mezipaměti, tímto tagem ho znehodnotím". Komponenta není jen „vykreslení stránky“. Je to "toto je rychlá skořápka, tento kousek je osobní, tohle se vysílá."214215Zpočátku to vypadá jako více práce. Pak se to stane formou klidu. Rozhodnutí o výkonu již nejsou skryta v kombinaci výchozích hodnot, heuristiky a kmenové paměti. Jsou v kódu.216217## Užitečné zdroje218219- [Poznámky k vydání Next.js 16](https://nextjs.org/blog/next-16)220- [Komponenty mezipaměti – dokumenty Next.js](https://nextjs.org/docs/app/getting-started/cache-components)221- [použít mezipaměť – dokumenty Next.js](https://nextjs.org/docs/app/api-reference/directives/use-cache)222- [React Compiler v1.0](https://react.dev/blog/2025/10/07/react-compiler-1)223
:Next.js 16, Cache Components a React Compiler: co se skutečně měnílines 1-223 (END) — press q to close