Episode ini membahas profiling dengan React DevTools dan tool browser, code splitting dengan bundle analysis dan tree shaking, optimasi Core Web Vitals, serta pengurangan payload JavaScript memakai server components dan dynamic import.

Optimasi performa bukan soal menebak: butuh pengukuran, diagnosis, lalu perbaikan yang terukur. Di episode 15 kita membangun proses itu dari awal — dari profiling, analisis bundle, metrik Web Vitals, sampai teknik konkret mengurangi JavaScript yang dikirim ke browser.
Langkah pertama adalah mengukur. React DevTools menampilkan profil rendering: komponen mana yang paling sering di-render dan berapa lama tiap render berlangsung. DevTools browser (Chrome/Edge) menyediakan Performance panel untuk merekam event load, network, dan rendering secara menyeluruh.
Alur yang disarankan: rekam interaksi yang lambat, amati profiler, temukan komponen yang mengonsumsi waktu, lalu perbaiki dan ukur ulang. Tanpa pengukuran awal, kalian hanya mengoptimasi secara acak.
Latih kebiasaan mengukur di setiap milestone: sebelum memulai fitur, catat baseline; setelah selesai, bandingkan hasilnya. Ini membangun budaya performa di tim alih-alih menunggu masalah muncul.
Profil yang baik dimulai dari reproduksi yang stabil: gunakan perangkat yang sama dan catat kondisi jaringan agar perbandingan antar sesi tetap adil.
Beberapa situasi yang sering muncul di profil: komponen yang di-render ulang karena props objek baru dibuat tiap render, event handler inline yang mengubah referensi, dan state yang disimpan terlalu tinggi di pohon komponen. Memoization dengan useMemo dan useCallback membantu, tapi hanya setelah diukur — jangan mengoptimasi tanpa data.
Next.js sudah melakukan code splitting per route — hanya JavaScript untuk halaman aktif yang dikirim. Untuk memverifikasi, pasang @next/bundle-analyzer dan jalankan build dengan analisis:
npm install --save-dev @next/bundle-analyzer
npx next build --analyzePerintah npx next build --analyze membuka laporan visual ukuran tiap bundle. Dari sini terlihat library mana yang menyumbang ukuran terbesar — biasanya chart, editor, atau date picker.
Tree shaking membuang kode yang tidak terpakai dari bundle. Praktik yang mendukungnya: import bernama dari library daripada import * as, hindari side-effect saat import, dan pilih library yang dirancang tree-shakeable. Bundle analyzer juga mengungkap kode yang seharusnya bisa dipangkas.
Rutinitas yang dianjurkan: jalankan bundle analyzer sebelum dan sesudah menambah dependency baru. Jika sebuah library menambah 50 kB untuk fitur yang jarang dipakai, cari alternatif atau alihkan ke dynamic import.
Selain ukuran per route, perhatikan juga jumlah request: terlalu banyak chunk kecil juga bisa melambatkan. Keseimbangan antara jumlah dan ukuran chunk adalah bagian dari seni optimasi bundle.
Core Web Vitals adalah standar pengalaman pengguna yang diukur Google:
Tiga yang pertama adalah Core Web Vitals; TTFB adalah metrik dukungan yang memengaruhi LCP. Optimasi gambar LCP, dimensi eksplisit untuk mencegah CLS, dan pengurangan JavaScript untuk INP adalah tiga perbaikan dengan dampak terbesar. Skor web vitals juga dipengaruhi infrastruktur: pilih platform dengan edge network dan HTTP/3 untuk memangkas TTFB, terutama untuk pengguna lintas negara.
INP mengukur latensi interaksi pengguna: sejak klik, ketukan, atau scroll, sampai respons terlihat. Penyebab umum INP buruk adalah JavaScript berat yang memblokir main thread. Kurangi pekerjaan utama dengan menyerahkan rendering ke server components dan membatasi update state yang tidak perlu. Sedangkan CLS biasanya berasal dari gambar tanpa dimensi, font yang memuat terlambat, dan iklan yang disisipkan setelah konten.
next/font agar teks tidak bergeser saat font dimuat.App Router menyediakan fungsi reportWebVitals untuk mengirim metrik ke layanan analitik:
"use client"
export function reportWebVitals(metric) {
console.log(metric.name, metric.value)
}Fungsi reportWebVitals(metric) dipanggil setiap kali metrik diukur. Kirim nilainya ke endpoint sendiri atau layanan seperti Vercel Analytics — topik observability akan dibahas lengkap di episode 22.
Server components tidak mengirim JavaScript ke browser — memindahkan rendering ke server mengurangi payload secara drastis. Untuk komponen klien yang berat, pakai dynamic import agar hanya dimuat saat dibutuhkan:
import dynamic from "next/dynamic"
const Chart = dynamic(() => import("@/components/Chart"), {
ssr: false,
loading: () => <p>Memuat grafik...</p>,
})dynamic() di atas memisahkan komponen Chart ke bundle tersendiri yang hanya diunduh saat dirender. Opsi ssr: false mencegah komponen berat ikut dirender di server. Strategi ini mencegah seluruh halaman membayar biaya komponen yang jarang terlihat.
Kombinasi server components, dynamic import, dan pembatasan library menghasilkan penurunan payload yang drastis. Target yang sehat: JavaScript di bawah 150 kB per route untuk halaman konten, lebih kecil lebih baik. Ukur dengan bundle analyzer setelah setiap perubahan besar agar tren ukuran tidak memburuk tanpa disadari. Perhatikan juga JSON besar yang diimport langsung dari file — ikut masuk bundle; pindahkan data besar ke API atau buat pipeline yang hanya menyertakan field yang dibutuhkan.
Selain itu, React Compiler yang diadopsi Next.js mengoptimasi memoization secara otomatis sehingga banyak penggunaan useMemo manual menjadi tidak perlu. Fitur ini mengurangi pekerjaan yang harus dijaga developer dan menjadikan optimasi performa lebih sederhana.
Inti yang harus dibawa pulang:
Di episode 16 selanjutnya kita akan membahas testing dan quality — unit testing dengan Jest dan React Testing Library, integration dan E2E testing dengan Playwright atau Cypress, accessibility testing, serta static analysis dengan ESLint dan type checking. Kualitas aplikasi kalian akan dijamin oleh otomatisasi.