spinny:~/writing $ vim nextjs-16-cache-components.md
1~2Évek óta az egyik legbosszantóbb kérdés a Next.js-ben: "Statikus vagy dinamikus ez az oldal?". Egyszerű kérdésnek tűnik, amíg fel nem hívja a `cookies()`-t, egy `fetch`-t különböző opciókkal, egy adatbázis-klienst, egy CMS-t, egy bevásárlókosarat vagy egy egyedi tartalmat.3~4A Next.js 16 azért érdekes, mert igyekszik kevésbé titokzatossá tenni ezt a beszélgetést. Nem szünteti meg a bonyolultságot, de megváltoztatja a mentális modellt: az útvonalak alapértelmezés szerint dinamikusak, a gyorsítótár deklarálja magát, ahol szükséges, és a `Suspense` a természetes mód a gyors shell-ek összeállítására olyan részekkel, amelyek frissek maradnak.5~6A funkció, amelyet meg kell érteni, a Cache Components. A Stable Turbopack, a React Compiler, a `proxy.ts` és az új érvénytelenítési API-k fontosak, de ugyanazt a problémát járják körül: gyors alkalmazásokat kell készíteni anélkül, hogy kitalálni kellene, mit döntött a keretrendszer a színfalak mögött.7~8## Mert ez számít9~10Egy igazi alkalmazásban nem csak „statikus oldalak” és „dinamikus oldalak” vannak. Különböző darabjai vannak különböző igényekkel.11~12A terméklap naponta néhányszor változhat. Az ár gyakrabban változhat. Az elérhetőségnek szinte élőnek kell lennie. A felhasználónév személyes. Az értékelések streamelhetők. Az oldalléc lehet stabil. A kocsi nem.13~14Ha mindent egy egységként kezel, mindig a két véglet egyikébe kerül:15~16- agresszív gyorsítótárazás és a régi adatok megtekintésének kockázata;17- dinamikus renderelés mindenhol és a szükségesnél rosszabb teljesítmény.18~19A Cache Components pontosan arra szolgál, hogy elkerülje ezt a téves választást.20~21## A modell a gyakorlatban22~23A `cacheComponents: true` használatával deklarálhatja, hogy mi tárolható a `"use cache"` használatával. Ezután az időtartamot és a címkéket társíthatja a `cacheLife()` és a `cacheTag()` címkékkel. A dinamikus részek dinamikusak maradnak, és a `Suspense` segítségével elkülöníthetők.24~25```mermaid26flowchart TD27 Request[Felhasználói kérés] --> Shell[Gyorsítótárazott shell]28 Request --> Dynamic[Dinamikus szakaszok]29 Shell --> FirstPaint[Az első gyors tartalom]30 Dynamic --> Stream[Streaming a Suspense-ben]31 Stream --> Complete[Teljes oldal]32```33~34A beállítás kicsi:35~36```typescript37// next.config.ts38import type { NextConfig } from 'next';39~40const nextConfig: NextConfig = {41 cacheComponents: true,42};43~44export default nextConfig;45```46~47A nagy változás nem a konfigurációban van. Ez abban áll, hogyan kezdi el írni az összetevőket.48~49```tsx50// app/products/[slug]/page.tsx51import { Suspense } from 'react';52import { cacheLife, cacheTag } from 'next/cache';53~54async function getProduct(slug: string) {55 'use cache';56~57 cacheLife('hours');58 cacheTag(`product:${slug}`);59~60 return db.product.findUnique({ where: { slug } });61}62~63async function ProductDetails({ slug }: { slug: string }) {64 const product = await getProduct(slug);65~66 return (67 <section>68 <h1>{product.name}</h1>69 <p>{product.description}</p>70 </section>71 );72}73~74async function LiveInventory({ slug }: { slug: string }) {75 const inventory = await db.inventory.findFirst({ where: { slug } });76 return <p>{inventory.quantity} pezzi disponibili</p>;77}78~79export default async function ProductPage({ params }: { params: Promise<{ slug: string }> }) {80 const { slug } = await params;81~82 return (83 <>84 <ProductDetails slug={slug} />85 <Suspense fallback={<p>Controllo disponibilità...</p>}>86 <LiveInventory slug={slug} />87 </Suspense>88 </>89 );90}91```92~93Az oldalnak nem kell teljes mértékben gyorsítótárazottnak vagy dinamikusnak lennie. A terméklap gyors és újrafelhasználható lehet. A készlet friss maradhat. A felhasználó azonnal lát valamit, anélkül, hogy megvárná a leglassabb részt.94~95## A `use cache` egy végrehajtható dokumentáció96~97Amit szeretek a `"use cache"`-ban, az az, hogy arra kényszerít, hogy kifejezze a szándékát. Amikor elolvas egy függvényt, azonnal megérti, hogy valaki úgy döntött: "ezek az adatok újra felhasználhatók".98~99Különösen hasznos, ha nem használja a `fetch`-t. Számos alkalmazás olvas adatokat a Prismából, a Drizzle-ből, a belső SDK-kból, a CMS-kliensekből vagy a szolgáltatási funkciókból. Ezekben az esetekben a régi, csak a `fetch` opciókon alapuló érvelés nem volt elég.100~101Egy ökölszabály:102~103- a cachea tartalma viszonylag stabil;104- használjon szemcsés címkéket;105- dinamikus engedélyeket, munkameneteket, kosarakat, értesítéseket és tranzakciós állapotokat hagy meg;106- tegyen lassú részeket a `Suspense`-ba;107- mérje meg, mielőtt azt mondaná, hogy "javítottuk a teljesítményt".108~109## Érvénytelenítse anélkül, hogy mindent eldobna110~111A gyorsítótár csak akkor hasznos, ha pontosan tudja frissíteni. Itt a `cacheTag`, `revalidateTag` és `updateTag` válik fontossá.112~113Példa:114~115```typescript116'use server';117~118import { updateTag } from 'next/cache';119~120export async function updateProductName(productId: string, name: string) {121 await db.product.update({122 where: { id: productId },123 data: { name },124 });125~126 updateTag(`product:${productId}`);127}128```129~130A fontos részlet a címke. A `product:${productId}` pontos határt mond. A `products` hatalmas vödröt mond. Eleinte kényelmes a hatalmas vödör; néhány hónap múlva ez lesz az oka annak, hogy érvénytelenít egy fél alkalmazást a cím megváltoztatása érdekében.131~132## Stable Turbopack: az a rész, amit minden nap hallasz133~134A Next.js 16 a Turbopackot a fejlesztés és építés központjába hozza. Nem ez a legköltőibb funkció, de ez az, amit munka közben érez: a szerver, amely korábban indul, gyorsabb frissítés, olyan felépítések, amelyek nem érzik úgy, mint egy kényszerű kávészünet.135~136Ennek ellenére csukott szemmel nem migrálnék egy egyedi bővítményekkel teli kódbázist. Ellenőrizném:137~138- helyi építés;139- nem szabványos import;140- MDX, SVG és CSS;141- Webpack bővítmények maradtak;142- kritikus oldalak;143- különbségek az építési időkben.144~145Az új projekteknél az alapértelmezésből indulnék ki. Éretteknek csinálnék egy kimért vándorlást.146~147## React Compiler: távolítsa el a zajt, ne a gondolatot148~149A React Compiler 1.0 stabil, és a Next.js 16 támogatja a `reactCompiler` használatával. Az ígéret a sok kézi memográfia csökkentése: kevesebb `memo`, kevesebb `useMemo`, kevesebb `useCallback` használt "biztonsági okokból".150~151```typescript152// next.config.ts153import type { NextConfig } from 'next';154~155const nextConfig: NextConfig = {156 reactCompiler: true,157};158~159export default nextConfig;160```161~162Nem kezelném varázsporként. A fordító akkor segít, ha a kód jól követi a React szabályait. Ha az összetevőknek furcsa mellékhatásai vannak, rejtett mutációk vagy rosszul használt horgok vannak, először ezt kell javítani.163~164Az egészséges módja annak, hogy kipróbáld:165~1661. frissítés `eslint-plugin-react-hooks`;1672. a tényleges jogsértések kijavítása;1683. engedélyezze egy ellenőrzött területen;1694. mérje az építési időt és a viselkedést;1705. csak akkor távolítsa el a kézi memorizálást, ha már nincs rá szükség.171~172A cél nem minden `useMemo` törlése. A cél az, hogy ne írjunk megelőző memoizációt, mert félünk a rendereléstől.173~174## `proxy.ts` és a hálózati határ175~176A régi `middleware.ts` `proxy.ts` lesz. Ez egy névváltoztatás, de logikus: ez a fájl a kérés határán van, nem hagyományos háttér-stílusú általános köztes szoftver.177~178```typescript179// proxy.ts180import { NextRequest, NextResponse } from 'next/server';181~182export default function proxy(request: NextRequest) {183 const isLoggedIn = Boolean(request.cookies.get('session'));184~185 if (!isLoggedIn && request.nextUrl.pathname.startsWith('/dashboard')) {186 return NextResponse.redirect(new URL('/login', request.url));187 }188~189 return NextResponse.next();190}191```192~193A szabály itt egyszerű: legyen kicsi. Átirányítás, hitelesítési útválasztás, fejlécek, lényeges átírások. Ha kezd úgy érezni, mint egy második háttérprogram, akkor valószínűleg túl sokat csinál.194~195## Hogy tényleg elvándorolnék196~197Nem kapcsolnám be egyszerre az összes funkciót. én ezt tenném:198~1991. Frissítem a Next, React és React DOM-ot;2002. Elindítom a hivatalos codemodet;2013. Javítom a hibás változásokat a `params`, `searchParams`, `cookies()`, `headers()` és `draftMode()`;2024. Áttelepítem a `middleware.ts`-t a `proxy.ts`-ba;2035. Ellenőrzöm a buildeket és a kritikus oldalakat;2046. Engedélyezem a Cache Components funkciót egy olyan szakaszon, ahol a gyorsítótár jelenleg súrlódást okoz;2057. Meghatározom a címkék és az érvénytelenítés konvencióit;2068. A React Compiler-t külön próbálom ki;2079. az előtti és utáni mutatók összehasonlítása.208~209A jó migráció nem az, amely az összes új funkciót használja. Ez teszi olvashatóbbá az alkalmazás viselkedését.210~211## Mi változik a gondolkodásmódban212~213A Next.js 16-ban az a leghasznosabb, hogy rákényszeríti a szándékok jobb megnevezésére. Egy funkció nem csak „szerezze le a terméket az adatbázisból”. Ez "szerezd be a terméket, órákig tárolhatom, ezzel a címkével érvénytelenítem". Egy komponens nem csak „megjeleníti az oldalt”. Ez a "ez a gyors shell, ez a darab személyes, ez streaming".214~215Eleinte több munkának tűnik. Aztán a nyugalom egy formájává válik. A teljesítményre vonatkozó döntések többé nem rejtőznek az alapértelmezett értékek, a heurisztika és a törzsi memória kombinációjában. Benne vannak a kódban.216~217## Hasznos források218~219- [Next.js 16 kiadási megjegyzések](https://nextjs.org/blog/next-16)220- [Gyorsítótár összetevői – Next.js docs](https://nextjs.org/docs/app/getting-started/cache-components)221- [gyorsítótár használata - Next.js docs](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~
NORMAL · nextjs-16-cache-components.md [readonly]223 lines · :q to close