Website Bisnis

Cara Marketer Indonesia Pasang Partial Prerendering di Next.js untuk Pangkas TTFB dari 720 ke 110 ms Tanpa Korbankan Slot Personalisasi di 2026

Vito Atmo
Vito Atmo·28 Mei 2026·0 kali dibaca·5 min baca
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:

LapisTugasLatensi
Cangkang statisHeader, hero, list dasar, footerDikirim langsung dari edge, sub-100 ms
Slot dinamisHarga regional, badge stok, greeting userStreamed 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

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

tsx
// 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

tsx
// 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

bash
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

ProyekTTFB SebelumTTFB SesudahCatatan
Nalesha (e-com parfum)720 ms110 msHarga regional tetap akurat
Yuanita Sekar (coaching)540 ms95 msGreeting user terjaga
vitoatmo.com (internal)380 ms70 msSlot 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.

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.

Bagikan

Artikel Terkait

#nextjs#ppr#partial-prerendering#ttfb#performance#marketer

Butuh website yang benar-benar bekerja?

Hubungi Vito untuk konsultasi gratis 15 menit.

WhatsApp Sekarang