Pendahuluan
Untuk aplikasi Nuxt 3 yang menyajikan katalog produk atau berita yang sering dibaca, mengandalkan permintaan API langsung di setiap halaman menyebabkan beban tinggi bagi server, latency yang meningkat, dan pengalaman pengguna yang tidak konsisten. Caching data membantu menekan jumlah permintaan ke backend sambil tetap memastikan data segar pada tingkat yang dapat dikendalikan. Artikel ini membahas strategi caching di seluruh lapisan: client, server, dan CDN, termasuk penggunaan useAsyncData, cache key konsisten, stale-while-revalidate, aturan route (route rules), dan header cache.
Selain implementasi teknis, kita juga membahas invalidasi, jenis data yang tidak boleh di-cache, serta jebakan umum seperti cache key yang berubah-ubah atau data usang.
Prinsip Dasar Caching di Nuxt 3
1. Tujuan caching dan trade-off
Caching bertujuan menyeimbangkan konsistensi data dan performa. Untuk halaman katalog atau berita, data biasanya tidak berubah tiap detik. Pilih jendela waktu (TTL) yang masuk akal, misalnya 60-300 detik, dan kombinasi stale-while-revalidate agar pengguna tidak menunggu saat data perlu di-refresh.
2. Cache key yang konsisten
Menggunakan cache key yang berubah-ubah (misalnya termasuk timestamp) membuat cache tidak terpakai. Kunci harus mencerminkan parameter yang benar-benar memengaruhi respons, misalnya endpoint, filter, bahasa, dan halaman paginasi. Contoh: catalogue:products:en:page=2.
3. Apa yang boleh dan tidak boleh di-cache
Data permissif untuk cache: daftar produk, metadata berita, statistik umum. Jangan cache data yang bersifat pribadi, sangat dinamis (saldo real-time), atau setiap endpoint yang me-return waktu server terkini. Jika perlu cache, sertakan header yang menegaskan Cache-Control: private, max-age=0, must-revalidate.
Implementasi Caching di Nuxt 3
Caching Client dengan useAsyncData
useAsyncData default menyimpan respons di server dan client. Untuk mengontrol caching API, gunakan parameter key dan stale seperti berikut:
const cacheKey = `catalogue:products:${locale}:page=${page}`
const { data, pending, refresh } = await useAsyncData(cacheKey, () =>
$fetch('/api/products', {
params: { locale, page }
}), {
watch: [locale, page],
lazy: false,
server: true,
// Client cache tetap menyimpan, namun kita kontrol sendiri lewat TTL
default: () => ({ items: [], meta: {} })
}
)
Untuk memanfaatkan stale-while-revalidate di client, panggil refresh() saat halaman fokus kembali atau melalui useIntervalFn dengan interval panjang. Tetap jaga cache key stabil, hindari mengikutkan timestamps.
Caching Server (Nitro) dan Header
Nuxt 3 berjalan di atas Nitro sehingga kita dapat menambahkan cache header di API atau endpoint server. Di server API, atur header Cache-Control untuk memanfaatkan caching pada layer CDN dan browser:
export default defineEventHandler(async (event) => {
const products = await fetchProductsFromDB(event.context.params)
setHeader(event, 'Cache-Control', 'public, max-age=60, stale-while-revalidate=120')
return products
})
Header ini memungkinkan CDN/browser menyajikan cache sampai 60 detik, lalu masih menerima versi lama saat versi baru diambil (stale-while-revalidate). Jika ingin cache lebih agresif, gunakan stale-if-error untuk menjaga page tetap tersedia saat backend down. Jangan lupa surrogate-control jika Anda ingin kontrol lebih spesifik untuk CDN tertentu.
Caching di CDN dan Route Rules
Atur route rules di Nuxt 3 (nuxt.config.ts) untuk menentukan header per route statis atau dynamic. Misalnya halaman katalog statis dapat di-cache lebih lama dibanding berita breaking news.
export default defineNuxtConfig({
routeRules: {
'/catalogue/**': {
swr: true,
cache: {
maxAge: 120,
staleWhileRevalidate: 300
}
},
'/news/breaking/**': {
headers: {
'cache-control': 'public, max-age=10, stale-while-revalidate=20'
}
}
}
})
Nuxt akan memasang header ke response dan CDN (misalnya Cloudflare, Vercel) akan memanfaatkannya. Pastikan route rule tidak menimpa header lain yang Anda pasang secara manual.
Praktik Invalidasi Cache
Cache harus kadaluarsa dengan mekanisme yang jelas. Pendekatan umum:
- TTL tetap: Header
max-agemenentukan waktu hidup data. - Cache-busting manual: Ubah cache key saat backend mengubah struktur data (misalnya menambahkan version).
- Webhook / Purge API: Ketika backend menerima pembaruan, panggil API CDN untuk purge cache dan trigger re-fetch di Nuxt.
Contoh pattern untuk katalog yang sering di-update oleh admin:
const cacheKey = `catalogue:products:v${apiVersion}:page=${page}`
Setiap deploy mayor atau schema change, tingkatkan apiVersion sehingga semua client otomatis mengabaikan cache lama.
Jika Anda menggunakan Nitro cache API (Server API Routes), dapat menambahkan invalidation via useRequestEvent untuk purge manual setelah mutation.
Data yang Tidak Boleh Di-cache dan Jebakan Umum
Tidak semua respons API layak di-cache. Hindari caching pada:
- Data user-specific tanpa autentikasi pada response.
- Token CSRF, header authorization.
- Informasi real-time seperti jumlah stok 1-2 menit lalu.
Jebakan yang sering terjadi:
- Cache key inconsistency: Menyertakan objek kontekstual seperti
new Date()membuat cache tidak pernah terpancing. - Header konflik: Set header cache di template dan route rules berbeda, sehingga CDN menolak cache.
- Men-cache error respons: Periksa status response dan jangan simpan cache saat error 4xx/5xx. Gunakan conditional caching:
if (response.status === 200) {
setHeader(event, 'Cache-Control', 'public, max-age=60, stale-while-revalidate=120')
}
Debugging cache dapat dilakukan dengan membuka tab Network di devtools dan memeriksa header Age, Cache-Control, serta validasi status 304.
Kesimpulan
Menerapkan caching berlapis di Nuxt 3 dapat mengurangi beban server secara signifikan tanpa mengorbankan konsistensi data. Dengan kombinasi useAsyncData dengan cache key konsisten, route rules untuk header, serta strategi invalidasi yang jelas, halaman katalog atau berita bisa tetap responsif bahkan pada traffic tinggi. Waspadai data yang tidak boleh di-cache dan pastikan header tidak saling bertentangan agar CDN dan browser memanfaatkan cache sebagaimana mestinya.
Eksperimen dengan TTL dan stale-while-revalidate untuk menemukan keseimbangan optimal antara kesegaran data dan performa. Gunakan tools pengukuran seperti Lighthouse untuk melihat dampak langsung pada waktu muat halaman.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!