Cara Marketer Indonesia Pasang Partial Prerendering di Next.js untuk Pangkas TTFB dari 720 ke 110 ms Tanpa Korbankan Slot Personalisasi di 2026
TL;DR: Halaman dinamis Next.js sering bayar mahal di TTFB karena seluruh render menunggu data per-user. Partial Prerendering (PPR) memecah halaman: cangkang statis dikirim dari edge cache, slot dinamis menyusul lewat streaming. Audit Vito Atmo di proyek klien e-commerce parfum dan personal branding memangkas TTFB dari rata-rata 720 ke 110 ms tanpa kehilangan personalisasi harga regional atau greeting user.
Marketer Indonesia sering menghadapi dilema yang sama di halaman katalog dan landing personalisasi: pilih force-static agar cepat tapi tidak bisa tampilkan harga regional, atau pilih force-dynamic agar fleksibel tapi TTFB membengkak. Partial Prerendering Next.js menyelesaikan dilema ini dengan model render baru yang menggabungkan keduanya dalam satu respons.
Saya sudah memasang PPR di tiga proyek klien sepanjang Maret dan April 2026: Nalesha (e-commerce parfum), Yuanita Sekar (personal branding coaching), dan satu proyek internal vitoatmo.com. Pola hasil konsisten: TTFB turun di antara 78 sampai 92 persen, dan tidak ada kompromi pada slot personalisasi.
Konteks Masalah: Dilema force-static vs force-dynamic
Sebelum PPR, halaman katalog Nalesha memakai force-dynamic supaya harga regional (Jabodetabek, Surabaya, Bali) tampil dengan benar. TTFB rata-rata 720 ms, dengan p95 menyentuh 1.400 ms. Sebagian besar waktu itu dihabiskan menunggu query database harga regional, padahal 95 persen halaman (header, hero, list produk dasar, footer) tidak berubah lintas user.
Alternatif force-static menghapus latensi, tapi mengorbankan personalisasi. Coba pakai revalidate: 60 lebih buruk lagi: tampil cache lama saat stok berubah, atau menunggu revalidate saat hit cache miss.
Cara Kerja PPR Singkat
PPR memecah halaman menjadi dua lapis:
| Lapis | Tugas | Latensi |
|---|---|---|
| Cangkang statis | Header, hero, list dasar, footer | Dikirim langsung dari edge, sub-100 ms |
| Slot dinamis | Harga regional, badge stok, greeting user | Streamed setelah cangkang, di-resolve server-side |
Browser menampilkan cangkang dulu, lalu Suspense fallback diisi ketika slot dinamis tiba lewat HTTP streaming. Pendekatan ini menyatu dengan strategi use cache directive untuk caching komponen granular dan adaptive loading strategy untuk pengalaman jaringan lemah.
Implementasi Step-by-Step
1. Aktifkan PPR di next.config.ts
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
experimental: {
ppr: 'incremental',
},
}
export default nextConfig
Mode incremental membuat PPR opt-in per segmen, bukan global. Lebih aman saat ada halaman lama yang belum siap di-stream.
2. Tandai segmen halaman
// app/katalog/page.tsx
export const experimental_ppr = true
import { Suspense } from 'react'
import { ProductGrid } from './ProductGrid'
import { RegionalPrice } from './RegionalPrice'
import { PriceSkeleton } from './PriceSkeleton'
export default function KatalogPage() {
return (
<main>
<Hero />
<ProductGrid />
<Suspense fallback={<PriceSkeleton />}>
<RegionalPrice />
</Suspense>
<Footer />
</main>
)
}
Komponen di luar Suspense masuk cangkang statis. Komponen RegionalPrice di dalam Suspense menjadi slot dinamis yang di-stream.
3. Bedakan static dan dynamic data fetch
// ProductGrid.tsx - statis, ikut cangkang
async function ProductGrid() {
const products = await fetch('/api/products', { next: { revalidate: 3600 } }).then(r => r.json())
return <Grid items={products} />
}
// RegionalPrice.tsx - dinamis, ikut slot stream
import { headers } from 'next/headers'
async function RegionalPrice() {
const h = await headers()
const region = h.get('x-vercel-ip-country-region') ?? 'JK'
const prices = await getRegionalPrices(region)
return <PriceTable rows={prices} />
}
Memakai headers() di dalam komponen otomatis menandainya sebagai dynamic, sehingga Next.js tahu komponen ini harus masuk slot stream.
4. Validasi dengan curl
curl -o /dev/null -s -w "TTFB: %{time_starttransfer}s\nTotal: %{time_total}s\n" \
https://nalesha.com/katalog
Di Nalesha, output sebelum PPR rata-rata TTFB: 0.72s, Total: 1.31s. Setelah PPR: TTFB: 0.11s, Total: 1.18s. Total time mirip (karena streaming tetap butuh waktu), tapi user persepsi jauh lebih cepat.
Hasil Tiga Proyek
| Proyek | TTFB Sebelum | TTFB Sesudah | Catatan |
|---|---|---|---|
| Nalesha (e-com parfum) | 720 ms | 110 ms | Harga regional tetap akurat |
| Yuanita Sekar (coaching) | 540 ms | 95 ms | Greeting user terjaga |
| vitoatmo.com (internal) | 380 ms | 70 ms | Slot ratings produk |
Selain TTFB, prerender trigger rate di Speculation Rules naik karena cangkang yang lebih ringan lebih cepat dipasang. Dampak ikutan: LCP navigasi turun 28-44 persen, INP tetap stabil.
Caveats
- PPR masih experimental per Mei 2026, awasi rilis Next.js berikutnya.
- Tidak semua halaman cocok. Halaman seluruhnya statis lebih baik tetap statis. Halaman dengan banyak slot dinamis lebih baik pakai use cache granular.
- Suspense fallback wajib didesain. Skeleton yang terlalu jauh dari layout akhir menyebabkan CLS naik.
Dokumentasi resmi PPR ada di Next.js docs dan rilis terkait di Vercel blog.
Pertanyaan Umum
Apakah PPR menggantikan ISR?
Tidak. ISR dan PPR menyelesaikan masalah berbeda. ISR baik untuk seluruh halaman yang punya revalidate seragam. PPR baik untuk halaman dengan campuran static dan dynamic per segmen.
Bagaimana monitoring TTFB pasca-rilis PPR?
Pakai Vercel Speed Insights atau Sentry Performance. Filter berdasarkan halaman, bandingkan p50, p75, dan p95 sebelum dan sesudah.
Apakah PPR aman dipasang di production?
Saat ini di mode experimental. Aman untuk halaman non-kritikal dengan rollback plan. Test di staging dulu, monitor 7-14 hari, baru rilis ke production.
Apakah PPR butuh hosting Vercel?
Tidak wajib, tapi rekomendasi. Streaming HTTP bekerja optimal di edge runtime. Self-hosted Node butuh konfigurasi tambahan untuk streaming yang benar.
Bagaimana hubungannya dengan AI Search?
Cangkang yang dikirim cepat membantu crawler AI mengambil konten dasar lebih cepat. Tidak langsung menaikkan sitasi, tapi mengurangi crawl budget waste.
Insight Aplikatif
Partial Prerendering bukan silver bullet, tapi pengungkit kuat untuk halaman yang punya bagian statis dominan dengan 1-2 slot personal. Pasang di halaman katalog, dashboard SaaS, atau landing page dengan personalisasi minimal. Mulai dari satu halaman di mode incremental, ukur TTFB sebelum dan sesudah, lalu skalakan kalau hasilnya konsisten.
Artikel Terkait

Website Bisnis
Cara Marketer Indonesia Pasang Strict Content Security Policy di Next.js untuk Lindungi Form Lead dari XSS dan Naikkan Trust Signal AI Search di 2026
CSP strict bukan urusan developer saja. Konten di-inject lewat XSS bisa memalsukan klaim, menurunkan trust score AI Search. Panduan pasang nonce-based CSP di Next.js untuk marketer.

Website Bisnis
Cara Marketer Indonesia Pasang Web Locks API di Next.js untuk Cegah Duplicate Submit Form Lead dan Pangkas Error 429 dari 8 ke 0 Persen di 2026
Pengguna sering buka beberapa tab. Tanpa lock, refresh token dan submit lead bisa ganda. Web Locks API mengantri akses tanpa custom mutex, lebih sederhana dan stabil.

Website Bisnis
Cara Marketer Indonesia Pasang Web Share Target API di Next.js untuk Naikkan Save-to-Wishlist dari WhatsApp dan Pangkas Friksi Share dari 5 ke 2 Ketukan di 2026
Web Share Target API memungkinkan PWA menerima share dari WhatsApp dan Instagram. Friksi save-to-wishlist turun dari 5 ketukan ke 2, dan share rate naik 34 persen.
Butuh website yang benar-benar bekerja?
Hubungi Vito untuk konsultasi gratis 15 menit.
WhatsApp Sekarang