NAME
nextjs-16-cache-components — Next.js 16, Cache Components a React Compiler: co se skutečně mění
SYNOPSIS
cat nextjs-16-cache-components.md
DESCRIPTION
Po 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.
Next.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é.
Funkce, 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.
Protože na této věci záleží
Ve skutečné aplikaci nemáte jen „statické stránky“ a „dynamické stránky“. Máte různé kousky s různými potřebami.
Produktový 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.
Pokud se vším zacházíte jako s jednou jednotkou, vždy skončíte v jednom ze dvou extrémů:
- agresivní ukládání do mezipaměti a riziko zobrazení starých dat;
- dynamické vykreslování všude a výkon horší, než je nutné.
Komponenty mezipaměti slouží právě k tomu, aby se zabránilo této falešné volbě.
Model v praxi
Pomocí 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.
Nastavení je malé:
// next.config.ts import type { NextConfig } from 'next'; const nextConfig: NextConfig = { cacheComponents: true, }; export default nextConfig;
Velká změna není v konfiguraci. Jde o to, jak začnete psát komponenty.
// app/products/[slug]/page.tsx import { Suspense } from 'react'; import { cacheLife, cacheTag } from 'next/cache'; async function getProduct(slug: string) { 'use cache'; cacheLife('hours'); cacheTag(`product:${slug}`); return db.product.findUnique({ where: { slug } }); } async function ProductDetails({ slug }: { slug: string }) { const product = await getProduct(slug); return ( <section> <h1>{product.name}</h1> <p>{product.description}</p> </section> ); } async function LiveInventory({ slug }: { slug: string }) { const inventory = await db.inventory.findFirst({ where: { slug } }); return <p>{inventory.quantity} pezzi disponibili</p>; } export default async function ProductPage({ params }: { params: Promise<{ slug: string }> }) { const { slug } = await params; return ( <> <ProductDetails slug={slug} /> <Suspense fallback={<p>Controllo disponibilità...</p>}> <LiveInventory slug={slug} /> </Suspense> </> ); }
Strá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.
use cache je spustitelná dokumentace
Na "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“.
Je 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.
Základní pravidlo:
- obsah cachea relativně stabilní;
- používat granulované značky;
- opustí dynamická oprávnění, relace, košíky, oznámení a transakční stavy;
- vložte pomalé části dovnitř
Suspense; - změřte, než řeknete „zlepšili jsme výkon“.
Zneplatnit, aniž byste všechno zahodili
Mezipaměť 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.
Příklad:
'use server'; import { updateTag } from 'next/cache'; export async function updateProductName(productId: string, name: string) { await db.product.update({ where: { id: productId }, data: { name }, }); updateTag(`product:${productId}`); }
Dů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.
Stabilní Turbopack: součást, kterou slyšíte každý den
Next.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.
To znamená, že bych nemigroval kódovou základnu plnou vlastních pluginů se zavřenýma očima. Zkontroloval bych:
- místní stavba;
- nestandardní dovoz;
- MDX, SVG a CSS;
- Webpack pluginy vlevo;
- kritické stránky;
- rozdíly v dobách výstavby.
U nových projektů bych začal od výchozího nastavení. U zralých bych udělal měřenou migraci.
React Compiler: odstraňte šum, ne myšlenku
React 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“.
// next.config.ts import type { NextConfig } from 'next'; const nextConfig: NextConfig = { reactCompiler: true, }; export default nextConfig;
Nechoval 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.
Zdravý způsob, jak to vyzkoušet:
- aktualizovat
eslint-plugin-react-hooks; - opravit skutečná porušení;
- povolit jej v kontrolované oblasti;
- měřit dobu výstavby a chování;
- ruční ukládání do paměti odstraňte pouze tehdy, když již není potřeba.
Cílem není vymazat každých useMemo. Cílem je přestat psát preventivní zapamatování, protože se bojíme vykreslování.
proxy.ts a hranici sítě
Ze 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.
// proxy.ts import { NextRequest, NextResponse } from 'next/server'; export default function proxy(request: NextRequest) { const isLoggedIn = Boolean(request.cookies.get('session')); if (!isLoggedIn && request.nextUrl.pathname.startsWith('/dashboard')) { return NextResponse.redirect(new URL('/login', request.url)); } return NextResponse.next(); }
Pravidlo 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.
Jak bych opravdu migroval
Nezapínal bych všechny funkce najednou. udělal bych toto:
- Aktualizuji Next, React a React DOM;
- Spouštím oficiální codemod;
- Opravuji zásadní změny na
params,searchParams,cookies(),headers()adraftMode(); - Migruji
middleware.tsnaproxy.ts; - Kontroluji sestavení a kritické stránky;
- Povoluji komponenty mezipaměti v sekci, kde mezipaměť aktuálně vytváří tření;
- Definuji konvence pro značky a zneplatnění;
- Zkouším React Compiler samostatně;
- srovnání metrik před a po.
Dobrá migrace není ta, která využívá všechny nové funkce. Díky tomu je chování aplikace čitelnější.
Co se mění ve způsobu myšlení
Na 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á."
Zpočá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.
Užitečné zdroje
METADATA
- date: 2026-05-24
- reading: 6 min
- author: Filippo Spinella
- tags: Next.js, React, Frontend, Performance