NAME
nextjs-16-cache-components — Next.js 16, Komponen Cache dan React Compiler: apa yang sebenarnya berubah
SYNOPSIS
cat nextjs-16-cache-components.md
DESCRIPTION
Selama bertahun-tahun, salah satu pertanyaan paling menjengkelkan di Next.js adalah: "Apakah halaman ini statis atau dinamis?". Sepertinya pertanyaan sederhana, sampai Anda menambahkan panggilan ke cookies(), fetch dengan opsi berbeda, klien database, CMS, keranjang belanja, atau konten khusus.
Next.js 16 menarik karena mencoba membuat percakapan ini tidak terlalu misterius. Ini tidak menghilangkan kompleksitas, tetapi mengubah model mental: rute bersifat dinamis secara default, cache mendeklarasikan dirinya sendiri jika diperlukan, dan Suspense menjadi cara alami untuk menyusun shell cepat dengan bagian-bagian yang tetap segar.
Fitur yang perlu dipahami adalah Cache Components. Turbopack Stabil, React Compiler, proxy.ts, dan API invalidasi baru memang penting, namun semuanya berkisar pada masalah yang sama: membangun aplikasi cepat tanpa harus menebak apa yang diputuskan oleh framework di balik layar.
Karena hal ini penting
Dalam aplikasi nyata Anda tidak hanya memiliki "halaman statis" dan "halaman dinamis". Anda memiliki bagian berbeda dengan kebutuhan berbeda.
Lembar produk dapat berubah beberapa kali sehari. Harga mungkin akan lebih sering berubah. Ketersediaan harus hampir aktif. Nama pengguna bersifat pribadi. Ulasan dapat dialirkan. Sidebar bisa stabil. Gerobak tidak.
Jika Anda memperlakukan segala sesuatu sebagai satu kesatuan, Anda selalu berakhir di salah satu dari dua ekstrem:
- caching yang agresif dan risiko melihat data lama;
- rendering dinamis di mana-mana dan kinerja lebih buruk dari yang diperlukan.
Komponen Cache berfungsi tepat untuk menghindari pilihan yang salah ini.
Model dalam praktiknya
Dengan cacheComponents: true, Anda dapat mendeklarasikan apa yang dapat di-cache menggunakan "use cache". Kemudian Anda dapat mengaitkan durasi dan tag dengan cacheLife() dan cacheTag(). Bagian dinamis tetap dinamis dan dapat diisolasi dengan Suspense.
Pengaturannya kecil:
// next.config.ts import type { NextConfig } from 'next'; const nextConfig: NextConfig = { cacheComponents: true, }; export default nextConfig;
Perubahan besar bukan pada konfigurasinya. Itu tergantung bagaimana Anda mulai menulis komponen.
// 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> </> ); }
Halaman tidak harus semuanya di-cache atau dinamis. Lembar produk dapat dibuat dengan cepat dan dapat digunakan kembali. Persediaan bisa tetap segar. Pengguna langsung melihat sesuatu, tanpa menunggu bagian paling lambat.
use cache adalah dokumentasi yang dapat dieksekusi
Hal yang saya suka tentang "use cache" adalah ia memaksa Anda untuk menyatakan niat secara eksplisit. Saat Anda membaca suatu fungsi, Anda langsung memahami bahwa seseorang telah memutuskan: "data ini dapat digunakan kembali".
Ini sangat berguna ketika Anda tidak menggunakan fetch. Banyak aplikasi membaca data dari Prisma, Gerimis, SDK internal, klien CMS, atau fungsi layanan. Dalam kasus tersebut, alasan lama yang hanya didasarkan pada opsi fetch tidaklah cukup.
Aturan praktisnya:
- konten cachea relatif stabil;
- gunakan tag granular;
- meninggalkan izin dinamis, sesi, keranjang, pemberitahuan, dan status transaksional;
- masukkan bagian yang lambat ke dalam
Suspense; - mengukur sebelum mengatakan "kami meningkatkan kinerja".
Batalkan tanpa membuang semuanya
Cache hanya berguna jika Anda dapat memperbaruinya secara akurat. Di sini cacheTag, revalidateTag dan updateTag menjadi penting.
Contoh:
'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}`); }
Detail penting adalah tagnya. product:${productId} memberi tahu batasan yang tepat. products menceritakan sebuah ember besar. Pada awalnya ember besar itu terasa nyaman; setelah beberapa bulan itu menjadi alasan Anda membatalkan setengah aplikasi untuk mengubah judul.
Turbopack Stabil: bagian yang Anda dengar setiap hari
Next.js 16 menghadirkan Turbopack ke pusat pengembangan dan pembangunan. Ini bukan fitur yang paling puitis, tapi itulah yang Anda rasakan saat bekerja: server yang dimulai lebih awal, penyegaran lebih cepat, build yang berhenti terasa seperti rehat kopi yang dipaksakan.
Meskipun demikian, saya tidak akan memigrasikan basis kode yang penuh dengan plugin khusus dengan mata tertutup. Saya akan memeriksa:
- bangunan lokal;
- impor nonstandar;
- MDX, SVG dan CSS;
- Plugin Webpack tersisa;
- halaman penting;
- perbedaan waktu pembuatan.
Untuk proyek baru, saya akan memulai dari default. Untuk yang sudah dewasa, saya akan melakukan migrasi terukur.
React Compiler: menghilangkan kebisingan, bukan pikiran
React Compiler 1.0 stabil dan Next.js 16 mendukungnya dengan reactCompiler. Janjinya adalah untuk mengurangi banyak memoisasi manual: lebih sedikit memo, lebih sedikit useMemo, lebih sedikit useCallback digunakan "untuk keamanan".
// next.config.ts import type { NextConfig } from 'next'; const nextConfig: NextConfig = { reactCompiler: true, }; export default nextConfig;
Saya tidak akan memperlakukannya seperti debu ajaib. Kompiler membantu ketika kode mengikuti aturan React dengan baik. Jika komponen memiliki efek samping yang aneh, mutasi tersembunyi, atau kaitan yang digunakan secara buruk, hal ini perlu diperbaiki terlebih dahulu.
Cara sehat untuk mencobanya:
- perbarui
eslint-plugin-react-hooks; - memperbaiki pelanggaran yang sebenarnya;
- aktifkan di area yang terkendali;
- mengukur waktu dan perilaku pembangunan;
- hapus memoisasi manual hanya jika tidak lagi diperlukan.
Tujuannya bukan untuk menghapus setiap useMemo. Tujuannya adalah berhenti menulis memoisasi preventif karena takut rendering.
proxy.ts dan batas jaringan
middleware.ts yang lama menjadi proxy.ts. Ini adalah perubahan nama, tetapi masuk akal: file itu berada di batas permintaan, ini bukan middleware generik bergaya backend tradisional.
// 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(); }
Aturannya di sini sederhana: jaga agar tetap kecil. Pengalihan, perutean autentikasi, header, penulisan ulang penting. Jika mulai terasa seperti backend kedua, mungkin fungsinya terlalu banyak.
Bagaimana saya benar-benar akan bermigrasi
Saya tidak akan mengaktifkan semua fitur sekaligus. Saya akan melakukan ini:
- Saya memperbarui Berikutnya, Bereaksi dan Bereaksi DOM;
- Saya meluncurkan codemod resmi;
- Saya memperbaiki perubahan yang mengganggu pada
params,searchParams,cookies(),headers()dandraftMode(); - Saya memigrasikan
middleware.tskeproxy.ts; - Saya memeriksa bangunan dan halaman penting;
- Saya mengaktifkan Komponen Cache di bagian tempat cache saat ini menimbulkan gesekan;
- Saya mendefinisikan konvensi untuk tag dan pembatalan;
- Saya mencoba React Compiler secara terpisah;
- perbandingan metrik sebelum dan sesudah.
Migrasi yang baik bukanlah yang menggunakan semua fitur baru. Hal inilah yang membuat perilaku aplikasi lebih mudah dibaca.
Apa yang mengubah cara berpikir
Hal yang paling berguna tentang Next.js 16 adalah memaksa Anda menyebutkan niat dengan lebih baik. Suatu fungsi bukan sekedar "mendapatkan produk dari database". Ini adalah "dapatkan produknya, saya dapat menyimpannya dalam cache selama berjam-jam, saya membatalkannya dengan tag ini". Sebuah komponen bukan sekedar "render halaman". Itu adalah "ini cangkang cepatnya, bagian ini bersifat pribadi, ini datang secara streaming."
Pada awalnya sepertinya lebih banyak pekerjaan. Kemudian menjadi suatu bentuk ketenangan. Keputusan kinerja tidak lagi tersembunyi dalam kombinasi default, heuristik, dan memori suku. Mereka ada di dalam kode.
Sumber yang bermanfaat
METADATA
- date: 2026-05-24
- reading: 6 min
- author: Filippo Spinella
- tags: Next.js, React, Frontend, Performance