spinny:~/writing $ less nextjs-16-cache-components.md
12Sa loob ng maraming taon, isa sa mga pinakanakakainis na tanong sa Next.js ay: "static o dynamic ba ang page na ito?". Tila isang simpleng tanong, hanggang sa magdagdag ka ng isang tawag sa `cookies()`, isang `fetch` na may iba't ibang opsyon, isang database client, isang CMS, isang shopping cart, o isang piraso ng custom na nilalaman.34Next.js 16 ay kawili-wili dahil sinusubukan nitong gawing mas misteryoso ang pag-uusap na ito. Hindi nito inaalis ang pagiging kumplikado, ngunit binabago nito ang modelo ng pag-iisip: ang mga ruta ay dynamic bilang default, ang cache ay nagdedeklara mismo kung saan kinakailangan, at ang `Suspense` ay nagiging natural na paraan upang bumuo ng mga mabilis na shell na may mga bahagi na nananatiling sariwa.56Ang feature na dapat maunawaan ay Cache Components. Ang Stable Turbopack, React Compiler, `proxy.ts`, at ang mga bagong invalidation API ay mahalaga, ngunit umiikot ang mga ito sa parehong problema: pagbuo ng mga mabilis na app nang hindi hinuhulaan kung ano ang napagpasyahan ng framework sa likod ng mga eksena.78## Dahil ang bagay na ito ay mahalaga910Sa isang totoong app hindi lang "static page" at "dynamic page" ang mayroon ka. Mayroon kang iba't ibang piraso na may iba't ibang pangangailangan.1112Ang sheet ng produkto ay maaaring magbago ng ilang beses sa isang araw. Ang presyo ay maaaring magbago nang mas madalas. Ang availability ay dapat na halos live. Ang username ay personal. Maaaring i-stream ang mga review. Ang sidebar ay maaaring maging matatag. Ang kariton ay hindi.1314Kung ituturing mo ang lahat bilang isang yunit, palagi kang napupunta sa isa sa dalawang sukdulan:1516- agresibong pag-cache at panganib na makakita ng lumang data;17- dynamic na pag-render sa lahat ng dako at mas masahol pa ang performance kaysa kinakailangan.1819Eksaktong nagsisilbi ang Cache Components upang maiwasan ang maling pagpiling ito.2021## Ang modelo sa pagsasanay2223Sa `cacheComponents: true`, maaari mong ideklara kung ano ang naka-cache gamit ang `"use cache"`. Pagkatapos ay maaari mong iugnay ang tagal at mga tag sa `cacheLife()` at `cacheTag()`. Ang mga dynamic na bahagi ay nananatiling dynamic at maaaring ihiwalay sa `Suspense`.2425```mermaid26flowchart TD27 Request[Kahilingan ng user] --> Shell[Naka-cache na shell]28 Request --> Dynamic[Mga dynamic na seksyon]29 Shell --> FirstPaint[Unang mabilis na nilalaman]30 Dynamic --> Stream[Streaming sa loob ng Suspense]31 Stream --> Complete[Buong pahina]32```3334Maliit ang setup:3536```typescript37// next.config.ts38import type { NextConfig } from 'next';3940const nextConfig: NextConfig = {41 cacheComponents: true,42};4344export default nextConfig;45```4647Ang malaking pagbabago ay wala sa config. Nasa kung paano mo simulan ang pagsusulat ng mga bahagi.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```9293Ang page ay hindi kailangang lahat ay naka-cache o lahat ay dynamic. Ang sheet ng produkto ay maaaring mabilis at magagamit muli. Maaaring manatiling sariwa ang imbentaryo. Nakikita kaagad ng user ang isang bagay, nang hindi naghihintay ng pinakamabagal na bahagi.9495## Ang `use cache` ay maipapatupad na dokumentasyon9697Ang bagay na gusto ko tungkol sa `"use cache"` ay pinipilit ka nitong gawing tahasan ang isang intensyon. Kapag nagbasa ka ng isang function, naiintindihan mo kaagad na may nagpasya: "maaaring magamit muli ang data na ito".9899Ito ay lalong kapaki-pakinabang kapag hindi mo ginagamit ang `fetch`. Maraming app ang nagbabasa ng data mula sa Prisma, Drizzle, internal SDKs, CMS client o service functions. Sa mga kasong iyon, hindi sapat ang lumang pangangatwiran batay lamang sa `fetch` na mga opsyon.100101Isang tuntunin ng hinlalaki:102103- medyo matatag ang nilalaman ng cachea;104- gumamit ng mga butil na tag;105- nag-iiwan ng mga dynamic na pahintulot, session, cart, notification at transactional na estado;106- ilagay ang mabagal na bahagi sa loob `Suspense`;107- sukatin bago sabihin ang "pinahusay namin ang pagganap".108109## Walang bisa nang hindi itinatapon ang lahat110111Ang cache ay kapaki-pakinabang lamang kung maa-update mo ito nang tumpak. Dito nagiging mahalaga ang `cacheTag`, `revalidateTag` at `updateTag`.112113Halimbawa: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```129130Ang mahalagang detalye ay ang tag. Ang `product:${productId}` ay nagsasabi ng isang tiyak na hangganan. `products` ay nagsasabi sa isang malaking balde. Sa una ang malaking balde ay komportable; pagkalipas ng ilang buwan ito ang nagiging dahilan kung bakit hindi mo wasto ang kalahati ng isang app para magpalit ng pamagat.131132## Stable Turbopack: ang bahaging naririnig mo araw-araw133134Dinadala ng Next.js 16 ang Turbopack sa sentro para sa pag-unlad at pagbuo. Hindi ito ang pinaka-mapatula na tampok, ngunit ito ang nararamdaman mo habang nagtatrabaho ka: server na nagsisimula nang mas maaga, mas mabilis na pag-refresh, bubuo na humihinto sa pakiramdam na parang sapilitang coffee break.135136Sabi nga, hindi ako maglilipat ng codebase na puno ng mga custom na plugin nang nakapikit. Susuriin ko:137138- lokal na pagtatayo;139- hindi karaniwang pag-import;140- MDX, SVG at CSS;141- Naiwan ang mga plugin ng Webpack;142- kritikal na mga pahina;143- mga pagkakaiba sa oras ng pagtatayo.144145Para sa mga bagong proyekto, magsisimula ako sa default. Para sa mga mature, gagawa ako ng sinukat na paglipat.146147## React Compiler: alisin ang ingay, hindi naisip148149Ang React Compiler 1.0 ay stable at ang Next.js 16 ay sinusuportahan ito ng `reactCompiler`. Ang pangako ay bawasan ang maraming manu-manong memoization: mas kaunti ang `memo`, mas kaunti ang `useMemo`, mas kaunti ang `useCallback` na ginamit "para sa kaligtasan."150151```typescript152// next.config.ts153import type { NextConfig } from 'next';154155const nextConfig: NextConfig = {156 reactCompiler: true,157};158159export default nextConfig;160```161162Hindi ko ito ituturing na parang magic dust. Nakakatulong ang compiler kapag sinusunod ng code ang mga panuntunan ng React. Kung ang mga sangkap ay may kakaibang epekto, mga nakatagong mutasyon o hindi wastong paggamit ng mga kawit, kailangan muna itong ayusin.163164Ang malusog na paraan upang subukan ito:1651661. update `eslint-plugin-react-hooks`;1672. ayusin ang mga aktwal na paglabag;1683. paganahin ito sa isang kontroladong lugar;1694. sukatin ang oras ng pagbuo at pag-uugali;1705. alisin lang ang manual memoization kapag hindi na ito kailangan.171172Ang layunin ay hindi burahin ang bawat `useMemo`. Ang layunin ay ihinto ang pagsusulat ng preventive memoization dahil natatakot kaming mag-render.173174## `proxy.ts` at ang hangganan ng network175176Ang lumang `middleware.ts` ay nagiging `proxy.ts`. Ito ay isang pagpapalit ng pangalan, ngunit makatuwiran: ang file na iyon ay nasa hangganan ng kahilingan, hindi ito tradisyonal na backend-style na generic na middleware.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```192193Ang panuntunan dito ay simple: panatilihin itong maliit. I-redirect, auth routing, mga header, mahahalagang rewrite. Kung magsisimula itong pakiramdam na parang pangalawang backend, malamang na sobra ang ginagawa nito.194195## Kung paano talaga ako magmigrate196197Hindi ko i-on ang lahat ng feature nang sabay-sabay. Gagawin ko ito:1981991. Ina-update ko ang Next, React at React DOM;2002. Inilunsad ko ang opisyal na codemod;2013. Inaayos ko ang mga nasira na pagbabago sa `params`, `searchParams`, `cookies()`, `headers()` at `draftMode()`;2024. Lumipat ako ng `middleware.ts` sa `proxy.ts`;2035. Sinusuri ko ang mga build at kritikal na pahina;2046. Pinagana ko ang Mga Bahagi ng Cache sa isang seksyon kung saan ang cache ay kasalukuyang lumilikha ng friction;2057. Tinutukoy ko ang mga kumbensyon para sa mga tag at kawalan ng bisa;2068. Sinusubukan kong hiwalay ang React Compiler;2079. paghahambing ng mga sukatan bago at pagkatapos.208209Ang magandang paglipat ay hindi ang isa na gumagamit ng lahat ng mga bagong tampok. Ito ang dahilan kung bakit mas nababasa ang gawi ng app.210211## Ano ang nagbabago sa paraan ng pag-iisip212213Ang pinakakapaki-pakinabang na bagay tungkol sa Next.js 16 ay pinipilit ka nitong pangalanan ang mga intensyon nang mas mahusay. Ang isang function ay hindi lamang "kunin ang produkto mula sa database". Ito ay "kunin ang produkto, maaari ko itong i-cache nang maraming oras, pinawalang-bisa ko ito sa tag na ito". Ang isang bahagi ay hindi lamang "i-render ang pahina". Ito ay "ito ang mabilis na shell, ang piraso na ito ay personal, ito ay dumarating sa streaming."214215Sa una parang mas maraming trabaho. Pagkatapos ito ay nagiging isang anyo ng kalmado. Ang mga pagpapasya sa pagganap ay hindi na nakatago sa isang kumbinasyon ng mga default, heuristics at memorya ng tribo. Nasa code sila.216217## Mga kapaki-pakinabang na mapagkukunan218219- [Next.js 16 na mga tala sa paglabas](https://nextjs.org/blog/next-16)220- [Mga Bahagi ng Cache - Next.js docs](https://nextjs.org/docs/app/getting-started/cache-components)221- [gumamit ng cache - 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
:Next.js 16, Cache Components at React Compiler: kung ano talaga ang nagbabagolines 1-223 (END) — press q to close