Next.js 16 Cache Components Tahun 2026: use cache, PPR dan Pertanyaan Interview
Pembahasan mendalam tentang Next.js 16 Cache Components: direktif use cache, Partial Pre-Rendering (PPR), cacheLife, cacheTag, dan pertanyaan interview nyata untuk developer senior.

Cache Components Next.js 16 merupakan perubahan terbesar dalam cara Next.js menangani caching sejak diperkenalkannya App Router. Model lama menyimpan semua data dalam cache secara default dan memerlukan pengecualian. Model baru tidak menyimpan apa pun dalam cache secara default dan memerlukan pengaktifan dengan direktif "use cache". Dengan Next.js 16.3, dirilis pada Agustus 2026, Cache Components mendapatkan Instant Navigations: seperangkat alat yang menghadirkan responsivitas mirip SPA ke aplikasi berbasis server.
Next.js 16 berpindah dari caching implisit (semua di-cache, keluar dengan API dinamis) ke caching eksplisit (tidak ada yang di-cache, masuk dengan "use cache"). Next.js 16.3 membangun hal ini dengan Partial Prefetching dan Instant Navigations, membuat model eksplisit terasa secepat aplikasi single-page.
Mengapa Next.js 16 Menggantikan Caching Implisit
Model caching implisit di Next.js 14-15 menyebabkan masalah prediktabilitas. Sebuah panggilan fetch di dalam Server Component secara otomatis dideduplikasi dan di-cache, tetapi apakah sebuah halaman statis atau dinamis bergantung pada API mana yang disentuhnya. Debugging perilaku cache memerlukan pemahaman beberapa lapisan tersembunyi: fetch cache, full-route cache, dan router cache.
Next.js 16 menghapus ketiga cache implisit tersebut. Setiap halaman dirender secara dinamis pada waktu request kecuali ditandai secara eksplisit dengan "use cache". Ekspor revalidate sudah tidak ada. unstable_cache digantikan oleh direktif "use cache" yang dikenali compiler. Blog post rilis Next.js 16 menjelaskan cakupan lengkap perubahan ini.
Pergeseran ini menukar optimasi otomatis dengan kontrol eksplisit. Performa mungkin awalnya menurun untuk aplikasi yang bergantung pada caching implisit, tetapi pengalaman debugging meningkat drastis: konten yang di-cache adalah karena kode menyatakannya, bukan karena heuristik framework.
Cara Kerja Direktif use cache pada Tiga Cakupan
Direktif "use cache" beroperasi pada tiga tingkat: file, komponen, dan fungsi. Memilih cakupan yang tepat adalah keputusan caching paling penting di Next.js 16.
Caching tingkat file menandai setiap ekspor async dalam file sebagai dapat di-cache. Ini cocok untuk halaman dengan konten yang sepenuhnya statis dan tanpa data spesifik pengguna.
"use cache"
import { getPricingPlans } from "@/lib/data"
// Entire page is cached as a static shell
export default async function PricingPage() {
const plans = await getPricingPlans()
return (
<section>
{plans.map((plan) => (
<PricingCard key={plan.id} plan={plan} />
))}
</section>
)
}Caching tingkat komponen meng-cache komponen individual dalam sebuah halaman. Ini memungkinkan Partial Pre-Rendering: komponen yang di-cache dirender ke dalam shell statis, sementara komponen dinamis lainnya di-stream pada waktu request.
async function ProductRecommendations({ categoryId }: { categoryId: string }) {
"use cache"
// categoryId becomes part of the automatic cache key
const products = await getTopProducts(categoryId)
return (
<ul>
{products.map((p) => (
<li key={p.id}>{p.name} - {p.price}</li>
))}
</ul>
)
}Caching tingkat fungsi menargetkan fungsi pengambilan data secara langsung. Ini menggantikan pola unstable_cache yang lama.
import { cacheLife } from "next/cache"
export async function getArticleBySlug(slug: string) {
"use cache"
cacheLife("hours")
// slug is automatically included in the cache key
const article = await db.article.findUnique({ where: { slug } })
return article
}Compiler menghasilkan cache key secara otomatis dari argumen fungsi. Tidak ada array keyParts manual, tidak ada workaround JSON.stringify. Argumen harus serializable (string, angka, objek plain). Melewatkan instance class atau fungsi sebagai argumen akan merusak serialisasi.
Instant Navigations di Next.js 16.3
Next.js 16.3 mengatasi kritik paling umum terhadap Server Components: navigasi terasa lambat karena memerlukan roundtrip jaringan. Instant Navigations memperbaiki ini dengan prefetching shell yang dapat digunakan kembali per rute, bukan per tautan.
Aktifkan Instant Navigations dengan dua flag di next.config.ts:
import type { NextConfig } from "next"
const nextConfig: NextConfig = {
cacheComponents: true,
partialPrefetching: true,
}
export default nextConfigDengan partialPrefetching: true, Next.js mengekstrak loading shell dari setiap rute dan meng-cache-nya di klien. Ketika pengguna mengklik tautan, shell dirender secara instan sementara konten dinamis di-stream masuk. Ini adalah pola responsivitas yang sama yang digunakan aplikasi single-page, tetapi tanpa meninggalkan rendering berbasis server.
Untuk setiap operasi async dalam sebuah rute, pilih: Stream dengan <Suspense> (loading state instan), Cache dengan "use cache" (UI cached instan), atau Block dengan export const instant = false (tunggu server). Dua yang pertama menghasilkan instant navigations.
Navigation Inspector di Next.js DevTools memungkinkan menjeda navigasi pada shell untuk melihat dengan tepat apa yang diprefetch. Instant Insights secara otomatis menampilkan navigasi lambat selama pengembangan, mengubahnya menjadi error yang dapat ditindaklanjuti.
Partial Pre-Rendering dengan Partial Prefetching
Partial Pre-Rendering (PPR) bersifat eksperimental di Next.js 14-15. Di Next.js 16, PPR sudah stabil dan terintegrasi langsung ke dalam Cache Components melalui cacheComponents: true. Next.js 16.3 memperluas ini dengan Partial Prefetching, yang mengubah cara shell dikirimkan ke klien.
Sebelum 16.3, Next.js mengirim permintaan prefetch untuk setiap tautan di viewport. Dengan Partial Prefetching, ia melakukan prefetch satu shell per rute. Dua puluh tautan chat yang mengarah ke /chat/[id] memicu satu prefetch, bukan dua puluh. Ini mengurangi overhead jaringan dan membuat strategi prefetch serupa dengan cara SPA melakukan code-split per rute.
import { Suspense } from "react"
import { UserGreeting } from "@/components/UserGreeting"
import { StaticSidebar } from "@/components/StaticSidebar"
import { RecentActivity } from "@/components/RecentActivity"
export default function DashboardPage() {
return (
<div className="grid grid-cols-12 gap-6">
{/* Cached static shell - prefetched and served instantly */}
<StaticSidebar />
<main className="col-span-9">
{/* Dynamic - streams in after shell renders */}
<Suspense fallback={<GreetingSkeleton />}>
<UserGreeting />
</Suspense>
{/* Dynamic - streams independently */}
<Suspense fallback={<ActivitySkeleton />}>
<RecentActivity />
</Suspense>
</main>
</div>
)
}Pohon keputusan rendering: komponen dengan "use cache" menjadi bagian dari shell statis. Komponen yang dibungkus dalam <Suspense> yang membaca cookies, headers, atau data request-specific lainnya di-stream secara dinamis. Untuk prefetching per-tautan di luar shell, tambahkan <Link prefetch={true}> ke tautan tertentu.
cacheLife Profiles: Menggantikan revalidate
Ekspor revalidate dari Next.js 15 sudah tidak ada. Sebagai gantinya, cacheLife() menyediakan profil bernama yang mengontrol durasi cache. Profil bawaan meliputi seconds, minutes, hours, days, weeks, dan max.
import { cacheLife } from "next/cache"
export async function getExchangeRates() {
"use cache"
cacheLife("minutes") // Revalidates every few minutes
const rates = await fetch("https://api.exchangerate.host/latest")
return rates.json()
}
export async function getCompanyInfo() {
"use cache"
cacheLife("weeks") // Rarely changes
return db.company.findFirst()
}Profil kustom didefinisikan dalam next.config.ts:
import type { NextConfig } from "next"
const config: NextConfig = {
cacheComponents: true,
cacheLife: {
// Custom profile for product data
product: {
stale: 300, // Serve stale for 5 minutes
revalidate: 3600, // Revalidate in background every hour
expire: 86400, // Hard expire after 24 hours
},
},
}
export default configMemusatkan profil dalam konfigurasi berarti satu perubahan menyesuaikan caching di seluruh aplikasi. Ini menghilangkan nilai revalidate: 3600 yang tersebar di codebase Next.js 15.
Satu aturan yang perlu diingat: cacheLife() harus hanya dieksekusi sekali per pemanggilan fungsi. Caching kondisional valid hanya jika satu cabang dieksekusi.
Siap menguasai wawancara React / Next.js Anda?
Berlatih dengan simulator interaktif, flashcards, dan tes teknis kami.
cacheTag dan updateTag untuk Invalidasi Tertarget
Tanpa cacheTag(), fungsi yang di-cache hanya dapat kadaluarsa berdasarkan waktu. Invalidasi sesuai permintaan memerlukan penandaan entri cache dan memanggil revalidateTag() atau updateTag() baru dalam Server Action.
import { cacheLife, cacheTag } from "next/cache"
export async function getProductById(id: string) {
"use cache"
cacheTag(`product-${id}`, "products")
cacheLife("days")
return db.product.findUnique({ where: { id } })
}"use server"
import { updateTag } from "next/cache"
export async function updateProduct(id: string, data: ProductUpdate) {
await db.product.update({ where: { id }, data })
// Invalidate this specific product AND the product list
updateTag(`product-${id}`)
updateTag("products")
}Perbedaan antara revalidateTag dan updateTag: keduanya melakukan invalidasi, tetapi updateTag adalah primitif yang direkomendasikan di Next.js 16.3, dirancang untuk bekerja dengan mulus dengan model caching baru. Tag mendukung hingga 256 karakter masing-masing, dengan maksimum 128 tag per entri cache.
Fungsi yang di-cache tanpa cacheTag() hanya dapat kadaluarsa berdasarkan waktu. Invalidasi sesuai permintaan tidak mungkin dilakukan. Ini mudah terlewatkan selama pengembangan awal dan menyakitkan untuk ditemukan ketika klien melaporkan data basi di produksi.
Keamanan: Varian use cache
Direktif "use cache" default membuat cache bersama. Kombinasi argumen apa pun menghasilkan entri cache yang dapat disajikan ke pengguna mana pun. Ini benar untuk data publik tetapi berbahaya untuk konten yang dipersonalisasi.
"use cache: private" membuat cache per pengguna yang menyertakan sesi saat ini dalam cache key. Ia dapat dengan aman mengakses cookies() dan headers() di dalam cakupan yang di-cache.
"use cache: remote" menyimpan cache di penyimpanan eksternal. Di lingkungan serverless (Vercel, AWS Lambda), cache in-memory default hilang saat cold start. Remote caching memastikan entri cache bertahan di seluruh instance fungsi, meskipun memerlukan roundtrip jaringan dan biasanya menimbulkan biaya platform.
// WRONG: User data in shared cache - data leak risk
export async function getUserDashboard(userId: string) {
"use cache"
return db.user.findUnique({
where: { id: userId },
include: { orders: true, preferences: true },
})
}
// CORRECT: Private cache scoped to the current user
export async function getUserDashboard() {
"use cache: private"
cacheLife("minutes")
const session = await cookies()
const userId = session.get("userId")?.value
return db.user.findUnique({
where: { id: userId },
include: { orders: true, preferences: true },
})
}Matriks keputusan untuk interview:
| Direktif | Cakupan | Gunakan Ketika |
|---|---|---|
"use cache" | Dibagikan, semua pengguna | Data publik: pricing, artikel, katalog produk |
"use cache: private" | Per sesi pengguna | Data personalisasi: dashboard, pengaturan, riwayat pesanan |
"use cache: remote" | Dibagikan, penyimpanan eksternal | Data high-traffic di lingkungan serverless |
Root Params di Next.js 16.3
Next.js 16.3 memperkenalkan root params, menyelesaikan prop-drilling berlebihan untuk segmen dinamis yang didefinisikan di atas root layout. Root params seperti [lang] secara efektif global dan diperlukan di seluruh pohon komponen.
import { lang } from "next/root-params"
export default async function PostPage(
props: PageProps<"/[lang]/posts/[slug]">
) {
const { slug } = await props.params
const language = await lang()
return (
<article>
<p>Language: {language}</p>
<p>Post: {slug}</p>
</article>
)
}Root params bekerja di dalam cakupan use cache, dan hanya params yang benar-benar dibaca yang menjadi bagian dari cache key. Ini membuat pola internasionalisasi lebih ergonomis tanpa merusak perilaku cache.
Menguji Instant Navigations
Helper test instant() untuk Playwright memungkinkan memastikan konten apa yang terlihat segera setelah navigasi, tanpa menunggu jaringan. Ini menangkap regresi di mana refactoring secara tidak sengaja membuat navigasi menjadi lambat.
import { expect, test } from "@playwright/test"
import { instant } from "@next/playwright"
test("product title is available immediately", async ({ page }) => {
await page.goto("/products/shoes")
// Assert what's visible without waiting for network
await instant(page, async () => {
await page.click('a[href="/products/hats"]')
await expect(page.locator("h1")).toContainText("Baseball Cap")
await expect(page.getByText("Checking inventory...")).toBeVisible()
})
await expect(page.getByText("12 in stock")).toBeVisible()
})Pola ini memastikan halaman yang dimaksudkan untuk dimuat secara instan tetap instan di seluruh perubahan kode. Navigation Inspector di DevTools melengkapi ini dengan memungkinkan inspeksi visual shell selama pengembangan.
Pertanyaan Interview: Yang Ditanyakan kepada Developer Senior
Pertanyaan-pertanyaan ini mencerminkan pola interview nyata tahun 2026 untuk posisi Next.js senior. Masing-masing menargetkan aspek spesifik dari Cache Components dan pembaruan 16.3.
P1: Jelaskan pergeseran dari caching implisit ke eksplisit di Next.js 16. Mengapa framework melakukan perubahan ini?
Next.js 14-15 meng-cache panggilan fetch dan halaman secara implisit. Debugging apakah halaman statis atau dinamis memerlukan penelusuran melalui beberapa lapisan cache tersembunyi. Model eksplisit dengan "use cache" membuat caching terlihat dalam source code. Trade-off-nya: performa mungkin awalnya turun untuk aplikasi yang bermigrasi dari caching implisit, tetapi developer mendapatkan kontrol dan prediktabilitas penuh.
P2: Apa saja tiga cakupan "use cache" dan kapan masing-masing harus digunakan?
Tingkat file untuk halaman yang sepenuhnya statis. Tingkat komponen untuk mencampur konten yang di-cache dan dinamis dalam satu halaman (pola PPR). Tingkat fungsi untuk meng-cache operasi pengambilan data tertentu. Pilihan cakupan menentukan granularitas cache dan batas invalidasi.
P3: Bagaimana Partial Prefetching di 16.3 berbeda dari prefetching di 16.0?
Di 16.0, Next.js mengirim permintaan prefetch untuk setiap tautan di viewport. Di 16.3 dengan partialPrefetching: true, ia melakukan prefetch satu shell yang dapat digunakan kembali per rute, yang di-cache di klien sepanjang sesi. Dua puluh tautan ke /chat/[id] memicu satu prefetch untuk shell rute chat, bukan dua puluh permintaan terpisah. Ini mengurangi overhead jaringan dan sejalan dengan cara SPA melakukan code-split.
P4: Sebuah tim meng-cache fungsi yang mengembalikan riwayat pesanan pengguna dengan "use cache". Apa yang terjadi?
Cache bersama menyimpan hasil dengan kunci berdasarkan argumen fungsi. Jika fungsi menerima parameter userId, pengguna yang berbeda mendapatkan entri cache yang berbeda, tetapi cache tetap merupakan infrastruktur bersama. Jika fungsi membaca userId dari cookies() alih-alih parameter, build gagal karena cookies() adalah API runtime yang dilarang dalam cakupan cache bersama. Solusinya: beralih ke "use cache: private" atau lewatkan user ID sebagai argumen eksplisit.
P5: Bagaimana cacheLife berbeda dari ekspor revalidate yang lama?
revalidate adalah satu angka (detik) yang diatur di tingkat halaman atau layout. cacheLife menggunakan profil bernama dengan tiga dimensi: stale (sajikan konten basi), revalidate (interval refresh background), dan expire (kadaluarsa keras). Profil dipusatkan di next.config.ts, sehingga satu perubahan mempengaruhi semua call site yang menggunakan profil tersebut.
P6: Apa perbedaan antara revalidateTag dan updateTag?
Keduanya menginvalidasi entri cache berdasarkan tag. updateTag adalah primitif yang direkomendasikan di Next.js 16.3, dirancang untuk terintegrasi dengan bersih dengan model caching eksplisit. Dalam praktiknya, keduanya berfungsi untuk invalidasi sesuai permintaan, tetapi updateTag adalah API yang berorientasi masa depan.
P7: Kapan harus menggunakan export const instant = false?
Ketika sebuah rute harus sengaja memblokir navigasi sampai server merespons. Misalnya, sebuah blog mungkin tidak pernah menampilkan loading shell untuk posting, ingin pembaca melihat konten lengkap segera. Ini mengecualikan dari error Instant Insights untuk rute tersebut.
Untuk lebih banyak pertanyaan interview Next.js data fetching, SharpSkill menyediakan modul latihan dengan sesi berwaktu dan penjelasan detail. Modul Next.js Server Actions mencakup pola Server Action yang berpasangan dengan invalidasi cache.
Checklist Praktis untuk Production Cache Components
- Aktifkan
cacheComponents: truedanpartialPrefetching: truedinext.config.ts - Audit setiap halaman: tambahkan
"use cache"ke halaman statis dan fungsi pengambilan data yang melayani konten publik - Bungkus semua konten dinamis (spesifik pengguna, request-time) dalam boundary
<Suspense>dengan fallback skeleton yang bermakna - Gunakan
"use cache: private"untuk fungsi apa pun yang mengakses cookies, headers, atau mengembalikan data personalisasi - Pertimbangkan
"use cache: remote"untuk data high-traffic di lingkungan serverless - Definisikan profil
cacheLifekustom untuk kategori data umum (data produk, sesi pengguna, konten statis) - Tambahkan
cacheTag()ke setiap fungsi yang di-cache yang mungkin memerlukan invalidasi sesuai permintaan - Gunakan
updateTag()untuk invalidasi sesuai permintaan di Server Actions - Uji dalam mode produksi dengan
next build && next startkarena perilaku caching dinext devberbeda secara signifikan - Tulis tes Playwright dengan
instant()untuk menangkap regresi navigasi - Gunakan Navigation Inspector di DevTools untuk memvisualisasikan shell yang diprefetch
Mulai berlatih!
Uji pengetahuan Anda dengan simulator wawancara dan tes teknis kami.
Sources
- Blog rilis Next.js 16.3 - Instant Navigations, Partial Prefetching, root params, peningkatan memori
- Pembahasan mendalam Instant Navigations - Model Stream/Cache/Block, Navigation Inspector, helper test
instant() - Dokumentasi direktif use cache - Ketiga varian, cacheLife, cacheTag, updateTag
- Blog rilis Next.js 16 - Pergeseran caching eksplisit asli
Yang Perlu Diingat tentang Next.js 16 Cache Components
- Next.js 16 menggantikan caching implisit dengan
"use cache"eksplisit pada cakupan file, komponen, dan fungsi - Next.js 16.3 menambahkan Instant Navigations: dengan
partialPrefetching: true, aplikasi terasa seresponsif SPA - PPR stabil di bawah
cacheComponents: true, menghadirkan shell statis dengan konten dinamis yang di-stream - Profil
cacheLifemenggantikanrevalidatedengan kontrol durasi cache tiga dimensi yang terpusat cacheTag+updateTagmemungkinkan invalidasi sesuai permintaan; tag yang hilang berarti kadaluarsa berdasarkan waktu saja"use cache: private"wajib untuk data spesifik pengguna untuk mencegah kebocoran data antar pengguna"use cache: remote"membantu lingkungan serverless mempertahankan cache di seluruh cold start- Root params dari
next/root-paramsmenyelesaikan prop-drilling untuk segmen dinamis global seperti[lang] - Pertanyaan interview di tahun 2026 berfokus pada pergeseran implisit-ke-eksplisit, Instant Navigations 16.3, Partial Prefetching, dan keamanan cache
Mulai berlatih!
Uji pengetahuan Anda dengan simulator wawancara dan tes teknis kami.
Bisakah kamu menemukan bug di React / Next.js?
Satu potongan kode nyata, satu bug tersembunyi, satu percobaan per hari. Tanpa akun untuk mencoba.

Ditulis oleh
Anthony Fillion-MailletPendiri SharpSkill
Developer fullstack selama lebih dari 10 tahun. Ia menjalankan SharpSkill dan bertanggung jawab atas semua yang diterbitkan di sini.
Diperbarui 25 Agustus 2026
Tag
Bagikan
Artikel terkait

Server Actions Next.js 16 di 2026: Mutasi, Revalidasi, dan Pertanyaan Wawancara
Cara Server Actions Next.js 16 menangani mutasi, revalidasi, status pending, UI optimistis, dan keamanan, lengkap dengan pertanyaan wawancara yang menguji setiap konsep.

React Compiler di Tahun 2026: Memoization Otomatis dan Pertanyaan Interview
Pelajari React Compiler untuk memoization otomatis, pipeline kompilasi, aturan React, dan pertanyaan interview yang sering muncul di tahun 2026.

React 19 Suspense dan Concurrent Rendering: Streaming SSR serta Pertanyaan Interview 2026
Panduan lengkap memahami React 19 Suspense, concurrent rendering, dan streaming SSR. Dilengkapi contoh kode praktis dan pertanyaan interview yang sering muncul di tahun 2026.