# Caching Next.js di 2025: ISR, SSR, dan Kapan Menggunakan Masing-masing

> Kerangka keputusan untuk memilih antara ISR, SSR, dan SSG di Next.js App Router — dengan angka performa nyata dan konfigurasi yang saya kirim.

URL: https://www.matthewswong.com/id/blog/nextjs-caching-isr-ssr-strategy/

- Author: Matthews Wong (https://www.matthewswong.com/id/about/)
- Published: 2025-06-10
- Updated: 2025-06-10
- Category: Web Dev

Waktu respons SSR biasanya berkisar 200-800ms tanpa caching. Cache hit ISR kembali dalam ~80ms. Pada 100.000 permintaan per hari, SSR biayanya 10-50x lebih mahal dalam komputasi daripada ISR yang menyajikan halaman yang di-cache. Saya belajar hal ini dengan cara yang sulit ketika saya meluncurkan dashboard Next.js dengan SSR untuk setiap halaman dan melihat biaya server melonjak. Strategi caching bukan hanya masalah performa — ini adalah keputusan biaya infrastruktur.

## Empat Mode Rendering: Apa yang Benar-benar Berubah

SSG menghasilkan HTML pada waktu build. ISR menghasilkan HTML pada permintaan pertama dan menyimpannya, memvalidasi ulang di latar belakang setelah interval waktu. SSR menghasilkan HTML pada setiap permintaan. RSC adalah model rendering yang bekerja di semua tiga — memindahkan rendering komponen ke server, mengurangi JS klien. Memahami mode mana yang digunakan memerlukan pemahaman dua hal: seberapa sering data berubah, dan apakah personalisasi memerlukan data waktu permintaan.

### ISR: Default Terbaik

ISR adalah default yang tepat untuk sebagian besar halaman. Ini memberi Anda performa situs statis (cache hit ~80ms TTFB, disajikan dari CDN) dengan kemampuan memperbarui konten tanpa rebuild penuh. Di Next.js App Router, Anda mengaktifkan ISR dengan mengatur `revalidate` di panggilan fetch atau konfigurasi segmen rute. Interval revalidasi 60 detik sesuai untuk daftar blog yang diperbarui beberapa kali sehari.

### Revalidasi On-Demand

Revalidasi berbasis waktu (revalidate: 60) sederhana tetapi tidak tepat — konten bisa basi hingga 60 detik setelah perubahan. Revalidasi on-demand dengan `revalidatePath()` atau `revalidateTag()` memungkinkan Anda membatalkan entri cache tertentu segera saat konten berubah. Untuk blog, panggil `revalidatePath('/blog')` dari webhook saat postingan baru diterbitkan.

> Dari pengalaman membangun aplikasi Next.js yang berat data: gunakan caching fetch di tingkat komponen, bukan tingkat halaman. Daripada mengatur `export const revalidate = 60` pada rute, atur opsi cache per-fetch: `fetch(url, '{ next: { revalidate: 60 }' '}')`. Ini memberi Anda kontrol granular — harga produk mungkin revalidate setiap 5 menit, sementara deskripsi produk dapat di-cache selama sehari.

## Kapan Anda Benar-benar Membutuhkan SSR

SSR sesuai ketika respons harus dipersonalisasi untuk pengguna spesifik yang membuat permintaan, dan personalisasi tersebut tidak dapat dilakukan sisi klien setelah shell statis dimuat. Contoh nyata: dashboard yang menampilkan data yang difilter berdasarkan organisasi pengguna yang masuk, halaman checkout yang harus membaca keranjang pengguna dari sesi, atau halaman yang kontennya dibatasi di balik pemeriksaan peran yang harus terjadi sisi server demi keamanan.

### Lapisan Cache App Router

Next.js App Router memiliki empat lapisan caching: Request Memoization (deduplication dalam satu render), Data Cache (persisten, lintas permintaan), Full Route Cache (HTML dan payload RSC, disimpan di edge CDN), dan Router Cache (sisi klien, di browser, untuk navigasi). Memahami semua empat lapisan penting karena mereka berinteraksi.

> **SSR Mahal di Skala — Profil Sebelum Berasumsi**

> Saya telah melihat pengembang default ke SSR untuk setiap halaman karena 'data perlu segar.' Dalam kebanyakan kasus, kesegaran data mentoleransi jendela revalidasi 30-60 detik, membuat ISR menjadi pilihan yang tepat. SSR berarti setiap pemuatan halaman memunculkan render sisi server — pada 100 pengguna bersamaan, itu 100 proses server simultan. Profil persyaratan kesegaran aktual Anda sebelum memilih SSR.

## Kueri Database dan Caching

Di Next.js App Router, komponen server dapat mengkueri database secara langsung. Kueri-kueri ini mendapat manfaat dari Data Cache jika dibungkus dalam `cache()` dari React. Untuk fungsi async non-fetch (seperti kueri Prisma), gunakan fungsi `cache()` React untuk memoize dalam satu render. Untuk caching lintas permintaan hasil database, `unstable_cache` dari Next.js menyediakan cache persisten dengan invalidasi berbasis tag.

## CDN dan Edge Caching

Halaman ISR dan SSG secara otomatis di-cache di edge CDN oleh Vercel. Untuk deployment self-hosted, Anda perlu mengkonfigurasi reverse proxy (nginx atau Caddy) untuk menyimpan respons. Server Next.js mengatur header Cache-Control berdasarkan konfigurasi rute Anda. CDN Anda harus menghormati header ini.

## Kerangka Keputusan Saya

Saya menggunakan pohon keputusan sederhana untuk setiap rute: Apakah memerlukan data spesifik pengguna yang harus sisi server? → SSR. Apakah data berubah lebih dari sekali per menit? → SSR atau ISR dengan interval pendek + revalidasi on-demand. Apakah berubah beberapa kali sehari? → ISR dengan revalidate 60-300d. Apakah sepenuhnya statis? → SSG dengan revalidasi on-demand untuk perubahan.

## Sumber & Bacaan Lebih Lanjut

- Next.js — Caching Documentation
- Code With Seb — SSR vs SSG vs ISR vs RSC Real-World Strategies
- Milan Jovanovic — Understanding ISR in Next.js

## Source links

- https://nextjs.org/docs/app/getting-started/caching
- https://www.codewithseb.com/blog/ssr-vs-ssg-vs-isr-vs-rsc-nextjs-strategies
- https://www.buildwithmatija.com/blog/understanding-incremental-static-regeneration-isr-guide

## FAQ

### Mengapa ISR sebaiknya menjadi pilihan default dibandingkan SSR untuk sebagian besar halaman Next.js?

ISR menyajikan halaman dari cache dengan TTFB ~80ms dari edge CDN, dibandingkan 200-800ms untuk SSR yang menghasilkan HTML pada setiap permintaan. Pada 100.000 permintaan per hari, biaya komputasi SSR 10-50x lebih mahal daripada ISR yang menyajikan halaman yang sudah di-cache. Untuk halaman yang tidak memerlukan data sisi server spesifik pengguna, ISR menghasilkan output yang sama dengan biaya infrastruktur yang jauh lebih rendah.

### Kapan SSR benar-benar lebih tepat digunakan daripada ISR?

SSR hanya sesuai ketika respons harus dipersonalisasi untuk pengguna spesifik yang membuat permintaan dan personalisasi tersebut tidak bisa dilakukan sisi klien setelah shell statis dimuat. Contoh nyatanya adalah dashboard yang difilter berdasarkan organisasi pengguna yang login, halaman checkout yang membaca keranjang pengguna dari sesi, atau halaman yang kontennya dibatasi di balik pemeriksaan peran sisi server demi keamanan. Untuk semua hal lainnya — termasuk postingan blog, halaman marketing, dan listing produk — ISR lebih cepat, lebih murah, dan sudah cukup.

### Apa perbedaan antara revalidasi berbasis waktu dan revalidasi on-demand pada ISR?

Revalidasi berbasis waktu (misalnya revalidate: 60) secara otomatis memperbarui halaman yang di-cache setelah interval tertentu, tetapi konten bisa tetap basi hingga durasi interval penuh setelah ada perubahan. Revalidasi on-demand menggunakan revalidatePath() atau revalidateTag() memungkinkan Anda membatalkan entri cache tertentu segera saat konten berubah — misalnya, memanggil revalidatePath('/blog') dari webhook ketika postingan baru diterbitkan. Revalidasi on-demand menggabungkan performa ISR dengan kesegaran konten yang mendekati real-time.

### Mengapa mengatur opsi cache di level fetch lebih baik daripada di level rute?

Mengatur opsi revalidate per panggilan fetch memberi Anda kontrol granular atas berbagai sumber data dalam satu halaman yang sama. Misalnya, harga produk mungkin perlu revalidate setiap 5 menit sementara deskripsi produk bisa di-cache selama satu hari penuh. Jika Anda mengatur export const revalidate = 60 di level rute, semua fetch pada halaman tersebut berbagi interval yang sama, yang bisa menyebabkan over-fetching atau data yang terlalu basi.

### Bagaimana empat lapisan cache App Router saling berinteraksi, dan mengapa ini penting?

Next.js App Router memiliki empat lapisan caching: Request Memoization (deduplication dalam satu render), Data Cache (persisten lintas permintaan), Full Route Cache (HTML dan payload RSC di edge CDN), dan Router Cache (cache navigasi sisi klien). Lapisan-lapisan ini berinteraksi dan bisa menyebabkan staleness yang tidak terduga — misalnya, menambahkan cache: 'no-store' pada sebuah fetch mengecualikannya dari Data Cache, tetapi Full Route Cache mungkin masih menyajikan halaman HTML yang basi jika Anda tidak juga menambahkan dynamic = 'force-dynamic' pada rute tersebut. Memahami keempat lapisan ini penting untuk men-debug perilaku caching yang tidak diharapkan.

---

- HTML version: https://www.matthewswong.com/id/blog/nextjs-caching-isr-ssr-strategy/
- English: https://www.matthewswong.com/en/blog/nextjs-caching-isr-ssr-strategy/
- Site index for agents: https://www.matthewswong.com/llms.txt
- Sitemap: https://www.matthewswong.com/sitemap.xml
- API description (OpenAPI): https://www.matthewswong.com/openapi.json
