Belajar Fullstack Developer - Performance & Optimization Lanjutan
Episode 25 of 28

Belajar Fullstack Developer - Performance & Optimization Lanjutan

Episode penutup seri Belajar Fullstack: teknik optimasi tingkat lanjut — profiling aplikasi, pengendalian bundle size, tuning query dan index database, serta workflow tuning produksi yang terukur dan berulang.

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Ini episode terakhir dari 28 — dan optimasi adalah tema yang pantas menutupnya, karena ia menyentuh semua yang sudah kalian pelajari: rendering (episode 3), data fetching (episode 8), caching (episode 15), keamanan (episode 16), dan observability (episode 24). Episode ini membahas performance & optimization lanjutan — bukan trik cepat, tapi metodologi: mengukur, menemukan penyebab sebenarnya, dan menerapkan perbaikan yang tepat.

Aturan pertamanya: optimasi tanpa pengukuran adalah tebakan. Setiap bagian dimulai dari ukuran — bukan intuisi.

Metodologi: Ukur → Temukan → Perbaiki → Ukur Lagi

100%

Disiplinnya: satu perubahan, satu pengukuran. Menerapkan tiga optimasi sekaligus membuat kalian tidak tahu mana yang bekerja (atau mana yang merusak).

1. Profiling: Menemukan Penyebab Sebenarnya

"Lambat" bukanlah diagnosis. Alat profiling membedah di mana waktu benar-benar terpakai:

LapisanAlatPertanyaan
BrowserChrome DevTools (Performance)Render atau JavaScript?
Servernext build --debug / tracing episode 24Render atau query?
DatabaseEXPLAIN ANALYZEFull scan atau index scan?
JaringanPerformance insights (Vercel)TTFB vs rendering?

Contoh pembuka mata yang klasik:

EXPLAIN ANALYZE — sebelum dan sesudah
EXPLAIN ANALYZE
SELECT * FROM "Note"
WHERE organization_id = 'org-1'
ORDER BY created_at DESC
LIMIT 10;
-- tanpa index:  Seq Scan ... 1800 ms
-- dengan index:  Index Scan ... 3 ms

Satu baris output Seq Scan vs Index Scan menjelaskan lebih banyak daripada seminggu menebak. 600x perbedaan dari satu index — itulah kenapa profiling selalu pertama.

Important

Rule profiling yang wajib: ukur di production (atau profil yang setara), bukan di development. Data development terlalu kecil — query yang "cepat" di lokal bisa jadi bencana dengan 10 juta baris. EXPLAIN ANALYZE dengan dataset nyata adalah pembeda besar antara optimasi nyata dan latihan.

2. Bundle Size: Menyusutkan JavaScript

Bundle yang gemuk memperlambat waktu interaksi (INP) meski server cepat. Tiga senjata utama:

Dynamic import — muat kode berat hanya saat dibutuhkan:

Dynamic import untuk bagian berat
const MarkdownEditor = dynamic(() => import("@/components/markdown-editor"), {
  loading: () => <EditorSkeleton />,
})

Tree-shaking — jangan import seluruh library:

Import yang bisa di-tree-shake
// JANGAN — menarik seluruh lodash
import _ from "lodash"
// BAIK — hanya yang dipakai
import orderBy from "lodash/orderBy"

Pemeriksaan terus-menerus — jadikan ukuran bagian dari CI:

Analisis bundle Next.js
pnpm build && pnpm next bundle-analyzer

Ingat aturan emas episode 3 dan 8: semakin banyak di server (Server Components), semakin sedikit yang harus dikirim ke browser. Sebagian besar "optimasi bundle" di aplikasi Next.js sebenarnya adalah "pindahkan ke server".

3. Tuning Database: Index dan Query

Di episode 22 kita membahas scaling; di sini detail tuning-nya. Tiga pola yang paling berdampak:

Composite index sesuai urutan query — kolom yang difilter = dulu, lalu yang di-ORDER BY:

Index untuk pola query umum
CREATE INDEX idx_notes_org_created
  ON "Note" (organization_id, created_at DESC);

Hindari SELECT * di query panas — ambil hanya kolom yang dirender:

Hanya kolom yang dibutuhkan
const notes = await prisma.note.findMany({
  where: { organizationId },
  select: { id: true, title: true, createdAt: true },
  take: 20,
})

Waspadai N+1 — jangan query dalam loop. Pola episode 8 (include relasi) atau query terpisah lalu gabung di memori, bukan query per baris:

Hindari N+1: pakai include, bukan loop
// JANGAN
const notes = await prisma.note.findMany({ where: { organizationId } })
const authors = await Promise.all(notes.map((n) => prisma.user.findUnique({ where: { id: n.authorId } })))
 
// BAIK — satu query dengan relasi
const notes = await prisma.note.findMany({
  where: { organizationId },
  include: { author: true },
})

Warning

Hati-hati premature optimization. Sebelum menambahkan index atau mencabut query, pastikan ada bukti query itu lambat atau sering — dari profiling/observability (episode 24), bukan dari perasaan. Index menambah biaya tulis dan memori; dynamic import menambah kompleksitas. Optimasi hanya layak jika data menunjukkan masalah.

4. Workflow Tuning Produksi yang Terukur

Optimasi bukan peristiwa sekali — ia proses berulang. Workflow produksi yang sehat:

  1. Baseline di observability: catat p95, p99, LCP, INP saat ini.
  2. Cari anomali (dari dashboard episode 24): halaman lambat, query mahal, bundle besar.
  3. Profil lapisan tersangka dengan alat yang tepat (tabel di atas).
  4. Terapkan satu perbaikan — index, caching (episode 15), atau perpindahan ke server.
  5. Ukur ulang & bandingkan dengan baseline. Pertahankan jika terbukti, kembalikan jika tidak.

Timeline nyatanya: kebanyakan kemenangan besar datang dari 3-4 perbaikan terukur per kuartal — bukan pesta optimasi mingguan.

Praktik: Tuning Produksi

Selesaikan dengan urutan berikut:

  1. Catat baseline dari dashboard observability: p95, LCP, error rate.
  2. Ambil halaman paling lambat → profiling di tiap lapisan (DevTools → tracing → EXPLAIN ANALYZE).
  3. Terapkan satu perbaikan yang paling berdampak (kemungkinan: composite index atau mengurangi bundle).
  4. Ukur ulang; bandingkan dengan baseline.
  5. Ulangi: langkah 2-4 sampai p95/LCP masuk target yang kalian tetapkan.
Ukur baseline halaman
curl -s -o /dev/null -w "TTFB: %{time_starttransfer}s total: %{time_total}s\n" \
  http://localhost:3000/notes

Penutup: Perjalanan Belajar Fullstack Kalian

Inti episode ini — dan seluruh seri:

  • Optimasi = metodologi berulang (ukur → temukan → perbaiki → ukur), bukan trik.
  • Profil dulu di lapisan yang tepat: DevTools, tracing, EXPLAIN ANALYZE.
  • Bundle size dikendalikan oleh dynamic import, tree-shaking, dan memindahkan kerja ke server.
  • Tuning database: composite index, pilih kolom, hindari N+1.
  • Jangan premature optimize — biarkan data berbicara.

Kalian mulai dari create-next-app dan prisma init di episode 0. Sekarang kalian telah melewati 28 episode: frontend dan backend, auth dan database, queue dan real-time, security dan scaling, AI dan observability. Kalian bukan lagi pemula — kalian fullstack developer. Terus bangun, terus ukur, dan sampai jumpa di proyek berikutnya!

Belajar Fullstack Developer - Performance & Optimization Lanjutan | Belajar Fullstack