spinny:~/writing $ less nextjs-16-cache-components.md
12Selama bertahun-tahun, salah satu soalan yang paling menjengkelkan dalam Next.js ialah: "Adakah halaman ini statik atau dinamik?". Nampaknya seperti soalan mudah, sehingga anda menambah panggilan ke `cookies()`, `fetch` dengan pilihan yang berbeza, pelanggan pangkalan data, CMS, troli beli-belah atau sekeping kandungan tersuai.34Seterusnya.js 16 menarik kerana ia cuba menjadikan perbualan ini kurang misteri. Ia tidak menghapuskan kerumitan, tetapi ia mengubah model mental: laluan adalah dinamik secara lalai, cache mengisytiharkan dirinya sendiri di mana diperlukan, dan `Suspense` menjadi cara semula jadi untuk mengarang cengkerang pantas dengan bahagian yang kekal segar.56Ciri yang perlu difahami ialah Komponen Cache. Turbopack Stabil, React Compiler, `proxy.ts` dan API pembatalan baharu adalah penting, tetapi ia berkisar pada masalah yang sama: membina apl pantas tanpa perlu meneka apa yang diputuskan oleh rangka kerja di sebalik tabir.78## Kerana perkara ini penting910Dalam apl sebenar, anda bukan sahaja mempunyai "halaman statik" dan "halaman dinamik". Anda mempunyai kepingan yang berbeza dengan keperluan yang berbeza.1112Helaian produk mungkin berubah beberapa kali sehari. Harga mungkin berubah lebih kerap. Ketersediaan mesti hampir langsung. Nama pengguna adalah peribadi. Ulasan boleh distrim. Bar sisi boleh menjadi stabil. Troli tidak.1314Jika anda menganggap segala-galanya sebagai satu unit, anda sentiasa berada dalam salah satu daripada dua keterlaluan:1516- caching agresif dan risiko melihat data lama;17- pemaparan dinamik di mana-mana dan prestasi lebih teruk daripada yang diperlukan.1819Komponen Cache berfungsi dengan tepat untuk mengelakkan pilihan palsu ini.2021## Model dalam amalan2223Dengan `cacheComponents: true`, anda boleh mengisytiharkan perkara yang boleh dicache menggunakan `"use cache"`. Kemudian anda boleh mengaitkan tempoh dan teg dengan `cacheLife()` dan `cacheTag()`. Bahagian dinamik kekal dinamik dan boleh diasingkan dengan `Suspense`.2425```mermaid26flowchart TD27 Request[Permintaan pengguna] --> Shell[Cache shell]28 Request --> Dynamic[Bahagian dinamik]29 Shell --> FirstPaint[Kandungan cepat pertama]30 Dynamic --> Stream[Menstrim dalam Suspense]31 Stream --> Complete[Halaman penuh]32```3334Persediaan adalah kecil:3536```typescript37// next.config.ts38import type { NextConfig } from 'next';3940const nextConfig: NextConfig = {41 cacheComponents: true,42};4344export default nextConfig;45```4647Perubahan besar tiada dalam konfigurasi. Ia terletak pada cara anda mula menulis komponen.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```9293Halaman tidak perlu semuanya dicache atau semua dinamik. Lembaran produk boleh cepat dan boleh digunakan semula. Inventori boleh kekal segar. Pengguna melihat sesuatu dengan segera, tanpa menunggu bahagian yang paling perlahan.9495## `use cache` ialah dokumentasi boleh laku9697Perkara yang saya suka tentang `"use cache"` ialah ia memaksa anda untuk menyatakan niat yang jelas. Apabila anda membaca fungsi, anda segera memahami bahawa seseorang telah memutuskan: "data ini boleh digunakan semula".9899Ia amat berguna apabila anda tidak menggunakan `fetch`. Banyak apl membaca data daripada Prisma, Drizzle, SDK dalaman, pelanggan CMS atau fungsi perkhidmatan. Dalam kes tersebut, alasan lama hanya berdasarkan pilihan `fetch` tidak mencukupi.100101Peraturan biasa:102103- kandungan cachea agak stabil;104- gunakan tag berbutir;105- meninggalkan kebenaran dinamik, sesi, troli, pemberitahuan dan keadaan transaksi;106- letak bahagian perlahan di dalam `Suspense`;107- ukur sebelum berkata "kami meningkatkan prestasi".108109## Batal tanpa membuang segala-galanya110111Cache hanya berguna jika anda boleh mengemas kininya dengan tepat. Di sini `cacheTag`, `revalidateTag` dan `updateTag` menjadi penting.112113Contoh: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```129130Perincian penting ialah tag. `product:${productId}` memberitahu sempadan yang tepat. `products` memberitahu baldi besar. Pada mulanya baldi besar itu selesa; selepas beberapa bulan ia menjadi sebab anda membatalkan separuh apl untuk menukar tajuk.131132## Turbopack Stabil: bahagian yang anda dengar setiap hari133134Next.js 16 membawa Turbopack ke pusat untuk pembangunan dan pembinaan. Ia bukan ciri yang paling puitis, tetapi ia adalah ciri yang anda rasa semasa anda bekerja: pelayan yang bermula lebih awal, menyegarkan lebih cepat, membina yang berhenti berasa seperti rehat kopi paksa.135136Yang berkata, saya tidak akan memindahkan pangkalan kod yang penuh dengan pemalam tersuai dengan mata tertutup. Saya akan menyemak:137138- binaan tempatan;139- modul bukan standard;140- MDX, SVG dan CSS;141- Pemalam Webpack ditinggalkan;142- halaman kritikal;143- perbezaan masa pembinaan.144145Untuk projek baharu, saya akan bermula dari lalai. Bagi yang matang, saya akan melakukan penghijrahan terukur.146147## React Compiler: keluarkan bunyi, bukan difikirkan148149React Compiler 1.0 adalah stabil dan Next.js 16 menyokongnya dengan `reactCompiler`. Janji adalah untuk mengurangkan banyak hafalan manual: kurang `memo`, kurang `useMemo`, kurang `useCallback` digunakan "untuk keselamatan".150151```typescript152// next.config.ts153import type { NextConfig } from 'next';154155const nextConfig: NextConfig = {156 reactCompiler: true,157};158159export default nextConfig;160```161162Saya tidak akan menganggapnya seperti debu ajaib. Pengkompil membantu apabila kod mengikut peraturan React dengan baik. Jika komponen mempunyai kesan sampingan yang pelik, mutasi tersembunyi atau cangkuk yang tidak digunakan, ia perlu diperbaiki terlebih dahulu.163164Cara sihat untuk mencubanya:1651661. kemas kini `eslint-plugin-react-hooks`;1672. membetulkan pelanggaran sebenar;1683. membolehkannya di kawasan terkawal;1694. mengukur masa dan tingkah laku binaan;1705. alih keluar hafalan manual hanya apabila ia tidak lagi diperlukan.171172Matlamatnya bukan untuk memadam setiap `useMemo`. Matlamatnya adalah untuk berhenti menulis hafalan pencegahan kerana kami takut untuk membuat.173174## `proxy.ts` dan sempadan rangkaian175176`middleware.ts` lama menjadi `proxy.ts`. Ia adalah perubahan nama, tetapi ia masuk akal: fail itu terletak pada sempadan permintaan, ia bukan perisian tengah generik gaya belakang tradisional.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```192193Peraturan di sini adalah mudah: pastikan ia kecil. Ubah hala, penghalaan pengesahan, pengepala, penulisan semula penting. Jika ia mula terasa seperti bahagian belakang kedua, ia mungkin melakukan terlalu banyak.194195## Bagaimana saya benar-benar akan berhijrah196197Saya tidak akan menghidupkan semua ciri sekaligus. Saya akan melakukan ini:1981991. Saya mengemas kini Seterusnya, React dan React DOM;2002. Saya melancarkan codemod rasmi;2013. Saya membetulkan perubahan yang rosak pada `params`, `searchParams`, `cookies()`, `headers()` dan `draftMode()`;2024. Saya berhijrah `middleware.ts` kepada `proxy.ts`;2035. Saya menyemak binaan dan halaman kritikal;2046. Saya mendayakan Komponen Cache pada bahagian di mana cache mencipta geseran pada masa ini;2057. Saya mentakrifkan konvensyen untuk teg dan pembatalan;2068. Saya cuba React Compiler secara berasingan;2079. perbandingan metrik sebelum dan selepas.208209Penghijrahan yang baik bukanlah yang menggunakan semua ciri baharu. Ini yang menjadikan gelagat apl lebih mudah dibaca.210211## Apakah perubahan dalam cara berfikir212213Perkara yang paling berguna tentang Next.js 16 ialah ia memaksa anda untuk menamakan niat dengan lebih baik. Fungsi bukan sekadar "mendapatkan produk daripada pangkalan data". Ia adalah "dapatkan produk, saya boleh cache selama berjam-jam, saya membatalkannya dengan tag ini". Komponen bukan sekadar "memberi halaman". Ia adalah "ini adalah cengkerang cepat, bahagian ini adalah peribadi, ini datang secara penstriman."214215Pada mulanya ia kelihatan seperti lebih banyak kerja. Kemudian ia menjadi satu bentuk ketenangan. Keputusan prestasi tidak lagi tersembunyi dalam gabungan lalai, heuristik dan ingatan puak. Mereka ada dalam kod.216217## Sumber yang berguna218219- [Nota keluaran Next.js 16](https://nextjs.org/blog/next-16)220- [Komponen Cache - Next.js docs](https://nextjs.org/docs/app/getting-started/cache-components)221- [gunakan 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, Komponen Cache dan React Compiler: apa yang sebenarnya berubahlines 1-223 (END) — press q to close