Optimasi Performa Next.js 14 SSR dengan Edge Caching Cloudflare
Dalam 15 menit ke depan, kita akan merakit stack ini dari nol sampai berjalan mulus. Pengalaman di lapangan membuktikan bahwa keluhan terbesar user bukan pada ukuran bundle JavaScript yang membengkak, melainkan pada angka Time to First Byte (TTFB) yang merayap di atas 800ms ketika aplikasi Next.js 14 kita mulai dihantam traffic global. Bayangkan server asal (origin) Anda di Singapura harus memproses SSR berdarah-darah untuk request dari Frankfurt. Tidak masuk akal. Mari kita pangkas latensi itu hingga di bawah 50ms secara global dengan memanfaatkan kombinasi mematikan antara App Router Next.js 14 dan Cloudflare Edge Caching.
1. Menu Kita Hari Ini & Alat yang Perlu Disiapkan
Sebelum mulai meracik, pastikan meja kerja kita bersih dan siap. Kita tidak butuh setup yang rumit, cukup siapkan bahan-bahan berikut:
- Sebuah aplikasi Next.js 14 yang sudah menggunakan App Router (
app/directory). - Domain aktif yang DNS-nya sudah diarahkan ke Cloudflare (proxy status: Proxied/Orange Cloud).
- Node.js versi 18.x atau lebih baru di mesin lokal Anda.
- Akses terminal dan secangkir kopi hitam hangat.
[!IMPORTANT] Pastikan Anda menggunakan Cloudflare Enterprise atau minimal plan Business jika membutuhkan Worker Routes yang kompleks, namun trik
Cache-Tagdan Edge Cache TTL yang akan kita racik hari ini tetap berjalan optimal bahkan di plan Free.
Sistem cache default Next.js sering kali membuat kita terjebak dalam dilema antara data basi atau server origin yang jebol. Kita akan selesaikan ini dengan memindahkan otak keputusan caching langsung ke pinggir internet (edge).
2. Peta Jalan Singkat: Apa yang Sedang Kita Rakit
Perjalanan kita singkat tapi padat. Pertama, kita akan membedah anatomi SSR Next.js 14 agar paham di titik mana latensi sering bocor. Kedua, kita meracik konfigurasi Cache-Control, stale-while-revalidate, dan memanfaatkan Cloudflare Workers atau Page Rules untuk mencegat request sebelum menyentuh Node.js. Terakhir, kita terapkan strategi ISR (Incremental Static Regeneration) tingkat lanjut agar halaman tetap segar tanpa mengorbankan kecepatan.
[!TIP] Anggap Cloudflare Edge sebagai pos pemeriksaan militer terdepan. Kita tidak ingin setiap turis (user) harus bertanya langsung ke istana raja (server origin) untuk hal-hal yang sudah tertulis di papan pengumuman.
Mari kita mulai dengan menyalakan mesin terminal dan menyiapkan fondasinya.
3. Langkah 1: Mempersiapkan Fondasi & Environment
Buka proyek Next.js 14 Anda. Kita perlu memastikan bahwa struktur routing dan fetch API memanfaatkan kemampuan caching bawaan App Router secara maksimal. Buat sebuah file konfigurasi environment .env.production untuk memastikan variabel global kita terdeteksi oleh Cloudflare adapter:
NODE_ENV=production
NEXT_PUBLIC_SITE_URL=https://domain-anda.com
Selanjutnya, pastikan Anda menggunakan library atau adapter deployment yang mendukung Edge runtime atau Node.js standar dengan header kustom. Jika Anda melakukan self-host di VPS (menggunakan Nginx di depan PM2), pastikan Nginx tidak merusak header cache yang kita kirim dari Next.js.
Perhatikan bagaimana server merespons saat ini dengan menjalankan curl -I https://domain-anda.com. Jika header X-Vercel-Cache atau CF-Cache-Status masih bernilai DYNAMIC atau MISS, itu tanda bahwa dapur kita belum efisien. Mari kita ubah.
4. Langkah 2: Meracik Konfigurasi Inti Tanpa Basa-basi
Masuklah ke direktori app/ Anda. Kita akan mengatur strategi caching di tingkat komponen menggunakan fetch options dan header HTTP kustom. Buka file halaman utama Anda, misalnya app/page.tsx, dan terapkan konfigurasi berikut:
// app/page.tsx
import React from 'react';
interface Post {
id: number;
title: string;
}
async function getCachedData(): Promise<Post[]> {
const res = await fetch('https://api.domain-anda.com/posts', {
// Memaksa Cloudflare dan Next.js untuk melakukan revalidate setiap 60 detik
next: { revalidate: 60, tags: ['posts-feed'] },
});
if (!res.ok) {
throw new Error('Gagal mengambil data dari origin backend');
}
return res.json();
}
export default async function Page() {
const posts = await getCachedData();
return (
<main className="p-8 max-w-4xl mx-auto">
<h1 className="text-3xl font-bold mb-6">Feed Global Super Cepat</h1>
<ul className="space-y-4">
{posts.map((post) => (
<li key={post.id} className="p-4 border rounded-lg shadow-sm">
{post.title}
</li>
))}
</ul>
</main>
);
}
Sekarang, agar Cloudflare mau menyimpan hasil SSR ini di edge server mereka di seluruh dunia, kita harus menyisipkan header Cache-Control yang ramah CDN. Buat file middleware.ts di akar direktori proyek Anda:
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const response = NextResponse.next();
// Beritahu Cloudflare Edge untuk cache halaman SSR selama 60 detik,
// dan layani versi stale hingga 3600 detik jika origin sedang sibuk.
if (request.nextUrl.pathname.startsWith('/')) {
response.headers.set(
'Cache-Control',
'public, s-maxage=60, stale-while-revalidate=3600'
);
}
return response;
}
export const config = {
matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
};
[!WARNING] Jangan pernah menyertakan Cookie sensitif atau header
Authorizationtanpa pengecualian di dalam Middleware untuk halaman publik. Cloudflare akan menolak melakukan cache pada request yang membawa header Cookie tertentu secara default demi alasan keamanan.
5. Langkah 3: Sentuhan Akhir Keamanan & Optimasi
Agar Cloudflare benar-benar mau meng-cache HTML hasil SSR Next.js kita, kita perlu masuk ke dashboard Cloudflare atau menggunakan Page Rules / Cache Rules. Buat Cache Rule baru dengan ketentuan:
- Field: URL Path
- Operator: equals
- Value:
domain-anda.com/(atau gunakan wildcarddomain-anda.com/*) - Cache Eligibility: Bypass cache for existing cookies (matikan atau sesuaikan agar Edge Cache TTL mengabaikan query string yang tidak penting).
- Edge Cache TTL: 1 jam (atau ikuti header
Cache-Controldari origin).
Untuk manajemen database dan backend pendukung seperti MySQL atau Redis di balik layar, pastikan query yang dipanggil oleh Next.js sudah terindeks dengan baik sehingga ketika cache miss terjadi, waktu tunggu origin tidak sampai membuat database timeout.
6. Tes Rasa: Memastikan Semuanya Berjalan Sempurna
Saatnya mencicipi masakan kita. Buka terminal Anda dan tembak server menggunakan curl secara beruntun:
curl -I https://domain-anda.com/
Perhatikan respons header pada pemanggilan kedua atau ketiga. Anda seharusnya melihat baris ajaib ini:
CF-Cache-Status: HIT
Age: 14
Cache-Control: public, s-maxage=60, stale-while-revalidate=3600
Jika CF-Cache-Status bernilai HIT, selamat! Artinya user dari belahan dunia manapun kini sedang melahap konten HTML Anda langsung dari server edge terdekat Cloudflare dengan latensi di bawah 50ms.
7. Pertolongan Pertama: Jika Terjadi Kendala Kecil
Di lapangan, teori tidak selalu berjalan mulus. Berikut pertolongan pertama untuk masalah klasik:
- Masalah: Header tetap bernilai
CF-Cache-Status: BYPASSatauDYNAMIC. - Solusi: Periksa apakah ada cookie session yang dikirim oleh browser atau middleware Anda. Hapus cookie tersebut untuk rute publik, atau atur Cloudflare Cache Rule untuk mengabaikan (ignore) cookie tertentu.
- Masalah: Data tidak mau diperbarui setelah data di database berubah.
- Solusi: Manfaatkan fitur
revalidateTagdari Next.js 14 yang dipicu via webhook API route saat ada data POST/PUT di backend Anda, lalu kombinasikan dengan Cloudflare Purge Cache API.
Kini infrastruktur web Anda sudah siap melayani jutaan hit tanpa membuat server origin megap-megap. Nikmati kopi Anda!