Cara Optimasi Next.js App Router agar PageSpeed Score 100

Cara Mengukur Performance Next.js App Router hingga Mencapai Score 100 PageSpeed
Cara Mengukur Performance Next.js App Router hingga Mencapai Score 100 PageSpeed

Ringkasan

  • Strategi memangkas bundle JavaScript secara drastis menggunakan Server Components (RSC) dan Dynamic Imports.
  • Teknik optimasi Core Web Vitals (LCP, INP, CLS) untuk mencapai skor hijau sempurna di PageSpeed Insights.
  • Panduan langkah-demi-langkah implementasi next/image dan next/font untuk performa maksimal.
  • Metode pengukuran performa yang akurat menggunakan Lighthouse, CrUX, dan Vercel Speed Insights.

Saya masih ingat rasa frustrasinya. Sudah menggunakan Next.js App Router, merasa sudah mengadopsi arsitektur paling "modern", namun saat dicek di PageSpeed Insights, skornya masih tertahan di angka 60–70. LCP (Largest Contentful Paint) buruk, bundle JavaScript membengkak, dan indikator Core Web Vitals berwarna merah. Bagi banyak pengembang, transisi ke App Router seringkali hanya fokus pada fitur, bukan pada bagaimana fitur tersebut berdampak pada performa akhir di sisi pengguna.

Setelah melakukan berbagai trial-and-error pada beberapa proyek produksi, saya menemukan pola konsisten yang mampu mendorong skor hingga 90–100. Artikel ini saya tulis berdasarkan pengalaman langsung mengoptimasi aplikasi Next.js App Router hingga mencapai skor hijau sempurna, baik untuk tampilan mobile maupun desktop. Fokus utamanya adalah: mengukur dengan metodologi yang benar, lalu memangkas JavaScript sebisa mungkin melalui pemanfaatan Server Components, dynamic import, dan optimasi aset visual.

1. Cara Mengukur Performance dengan Metodologi yang Benar

Kesalahan umum pengembang adalah terlalu percaya pada satu kali pengujian. Performa web bersifat fluktuatif tergantung pada koneksi, perangkat, dan beban server. Untuk mendapatkan data yang valid, lakukan pengukuran di beberapa kondisi berikut:

  • PageSpeed Insights (PSI): Alat utama yang menggabungkan lab data (simulasi) dan field data (data nyata dari pengguna melalui Chrome User Experience Report/CrUX).
  • Lighthouse di Chrome DevTools: Gunakan mode Incognito untuk menghindari interferensi dari ekstensi browser, dan aktifkan throttling mobile untuk mensimulasikan perangkat kelas menengah dengan koneksi 4G.
  • Vercel Analytics & Speed Insights: Jika Anda menghosting proyek di Vercel, fitur ini memberikan data Real User Monitoring (RUM) yang jauh lebih akurat daripada simulasi lab.

Memahami Core Web Vitals (CWV)

Jangan hanya mengejar angka 100, tetapi fokuslah pada metrik yang benar-benar dirasakan pengguna:

  1. LCP (Largest Contentful Paint): Mengukur waktu yang dibutuhkan untuk merender elemen terbesar di layar. Target: < 2.5 detik.
  2. INP (Interaction to Next Paint): Metrik baru pengganti FID yang mengukur responsivitas halaman terhadap input pengguna. Target: < 200 ms.
  3. CLS (Cumulative Layout Shift): Mengukur stabilitas visual agar konten tidak "melompat-lompat" saat loading. Target: < 0.1.

2. Memaksimalkan Server Components (RSC) untuk Memangkas Bundle

React Server Components (RSC) adalah senjata terkuat di Next.js App Router. Secara default, semua komponen di dalam direktori app/ adalah Server Component. Artinya, kode tersebut dieksekusi di server dan hasilnya dikirim sebagai HTML, bukan sebagai JavaScript yang harus diproses oleh browser.

Semakin banyak logika yang Anda biarkan di server, semakin kecil bundle JavaScript yang harus diunduh oleh client. Hal ini secara langsung menurunkan waktu Total Blocking Time (TBT) dan mempercepat First Contentful Paint (FCP).

Implementasi Praktis

Berikut adalah contoh bagaimana memisahkan logika server dan client secara efisien:

// app/dashboard/page.tsx (Server Component by default)
import { getHeavyData } from '@/lib/data'
import ClientChart from './ClientChart' // Hanya bagian interaktif yang client

export default async function DashboardPage() {
  // Fetching data dilakukan di server, tidak masuk ke bundle JS client
  const data = await getHeavyData() 

  return (
    <div>
      <h1>Dashboard Analitik</h1>
      <HeavyTable data={data} /> {/* Tetap Server Component, nol JS di client !}
      <ClientChart data={data.summary} /> {/* Hanya komponen ini yang mengirim JS ke browser *}
    </div>
  )
}

Prinsip Utama Optimasi RSC:

  • Biarkan komponen sebagai Server Component selama mungkin.
  • Gunakan direktif 'use client' hanya pada level daun (leaf components) yang benar-benar membutuhkan interaktivitas seperti useState, useEffect, atau event listener.
  • Hindari menaruh 'use client' di layout.tsx atau page.tsx tingkat atas, karena hal ini akan memaksa semua komponen anak di bawahnya menjadi Client Components.

3. Strategi Dynamic Import untuk Komponen Berat

Tidak semua komponen harus dimuat saat halaman pertama kali dibuka. Komponen seperti modal, editor teks, atau library chart yang kompleks seringkali menjadi penyebab utama membengkaknya bundle size. Di sinilah next/dynamic berperan.

Dengan dynamic import, Next.js akan memisahkan kode komponen tersebut ke dalam chunk terpisah yang hanya akan diunduh saat dibutuhkan (code splitting).

Contoh Penerapan Dynamic Import

import dynamic from 'next/dynamic'

// Memuat komponen hanya saat dibutuhkan
const HeavyEditor = dynamic(() => import('@/components/HeavyEditor'), {
  loading: () => <p>Loading editor...</p>,
  ssr: false // Matikan SSR jika komponen hanya bisa berjalan di browser (misal: akses window/document)
})

// Untuk named export
const Chart = dynamic(() => 
  import('@/components/Chart').then((mod) => mod.Chart)
)

Gunakan teknik ini untuk:

  • Rich Text Editors: Seperti TinyMCE atau CKEditor yang memiliki bundle sangat besar.
  • Visualisasi Data: Library seperti Recharts atau Chart.js.
  • Komponen Interaktif Tersembunyi: Modal konfirmasi, dropdown kompleks, atau PDF viewer.

4. Optimasi Gambar dan Aset Visual yang Presisi

Komponen next/image sudah sangat canggih, namun penggunaan yang salah tetap bisa merusak skor LCP. Gambar yang terlalu besar atau tidak teroptimasi adalah penyebab utama skor PageSpeed rendah pada perangkat mobile.

import Image from 'next/image'

<Image
  src="/hero-banner.webp"
  alt="Deskripsi Gambar Hero"
  width={1200}
  height={630}
  priority // KRUSIAL: Beritahu browser untuk memuat gambar ini lebih dulu (LCP)
  sizes="(max-width: 768px) 100vw, 50vw"
  quality={80}
/>

Checklist Optimasi Gambar:

  • Format Modern: Gunakan WebP atau AVIF. Next.js melakukan konversi otomatis jika dikonfigurasi dengan benar.
  • Atribut sizes: Jangan biarkan browser mengunduh gambar ukuran desktop untuk layar mobile. Definisikan sizes agar Next.js mengirimkan ukuran gambar yang tepat.
  • Priority Property: Gunakan priority hanya untuk gambar yang muncul di bagian atas layar (above-the-fold). Terlalu banyak gambar priority justru akan memperlambat loading.
  • Avoid Layout Shift: Selalu tentukan width dan height untuk mencegah CLS.

5. Teknik Lanjutan untuk Performa Ekstrem

Jika Anda sudah menerapkan poin di atas namun skor masih belum mencapai 100, coba terapkan teknik berikut:

Streaming dan Suspense

Jangan biarkan seluruh halaman menunggu fetch data yang lambat. Gunakan loading.tsx atau <Suspense> untuk melakukan streaming konten secara bertahap. Ini meningkatkan perceived performance karena pengguna melihat bagian halaman yang sudah siap lebih cepat.

Optimasi Font dengan next/font

Font eksternal sering menyebabkan CLS karena terjadi perubahan font saat loading (FOIT/FOUT). Gunakan next/font/google untuk mengunduh font secara lokal saat build time, sehingga tidak ada request tambahan ke server Google saat runtime.

Analisis Bundle dengan @next/bundle-analyzer

Anda tidak bisa mengoptimasi apa yang tidak bisa Anda ukur. Instal bundle analyzer untuk melihat library mana yang paling banyak memakan ruang:

npm install @next/bundle-analyzer

Setelah diinstal, Anda bisa melihat visualisasi ukuran setiap chunk JS. Jika menemukan library besar yang hanya dipakai di satu halaman, segera pindahkan ke dynamic import.

6. Alur Kerja Optimasi (Step-by-Step)

Untuk hasil maksimal, ikuti urutan optimasi berikut agar Anda tidak membuang waktu pada hal yang dampaknya kecil:

  1. Audit Awal: Jalankan PageSpeed Insights dan catat metrik yang merah (LCP, INP, atau CLS).
  2. Refactor ke RSC: Pindahkan logika data fetching dan rendering statis ke Server Components.
  3. Code Splitting: Identifikasi komponen berat melalui bundle analyzer dan terapkan dynamic import.
  4. Visual Tuning: Optimasi gambar LCP dengan priority dan perbaiki sizes.
  5. Font & CSS: Implementasikan next/font dan hapus CSS yang tidak terpakai.
  6. Third-party Scripts: Gunakan next/script dengan strategi lazyOnload untuk script seperti Google Analytics atau chat widget.
  7. Validasi Akhir: Ukur ulang dan bandingkan hasilnya.

Kesimpulan

Mencapai skor 100 di PageSpeed Insights dengan Next.js App Router bukan sekadar keberuntungan, melainkan hasil dari disiplin dalam mengelola pengiriman JavaScript ke browser. Kunci utamanya adalah meminimalkan beban client-side dengan memaksimalkan kapabilitas server-side.

Ingatlah bahwa performa bukan sekadar angka, tetapi tentang pengalaman pengguna. Halaman yang cepat meningkatkan konversi dan SEO. Jangan pernah mengira-ngira; selalu gunakan siklus Ukur → Perbaiki → Ukur Lagi.

Jika Anda sedang berjuang menaikkan skor PageSpeed proyek Anda, jangan ragu untuk melakukan audit struktur komponen. Seringkali, hanya dengan memindahkan satu 'use client' dari level layout ke level komponen kecil, Anda bisa melihat peningkatan skor yang signifikan.

Solusi yang relevan

Service

Jasa Pembuatan Website

Pembuatan website custom yang cepat, modern, dan siap jualan.

Lihat Solusi →

Dapatkan Artikel Terbaru!

Berlangganan newsletter kami untuk mendapatkan tips dan insight menarik langsung ke inbox Anda.

Kami tidak akan pernah membagikan email Anda (No Spam).