Lupakan Pages Router Ini Cara Kami Turunkan Waktu Loading Next.js Sampai 40 Persen

Lupakan Pages Router Ini Cara Kami Turunkan Waktu Loading Next.js Sampai 40 Persen
Photo by David Pupăză/Unsplash

Next.js itu memang game changer banget di dunia web development. Siapa coba yang nggak suka sama fitur server-side rendering (SSR) atau static site generation (SSG)-nya? Tapi, seiring project makin gede, seringkali kita kejebak sama satu isu klasik: loading time mulai terasa berat, apalagi di device yang spesifikasinya pas-pasan.

Dulu, zaman Pages Router masih jadi raja, solusi untuk ngebutin website itu seringkali ribet. Kita harus mati-matian ngurusin bundle splitting manual, mikirin kapan harus pakai getServerSideProps atau getStaticProps, dan intinya, banyak banget beban yang ujung-ujungnya lari ke sisi klien (browser user). Hasilnya? Time to Interactive (TTI) jadi lambat.

Di Javapixa Creative Studio, kami sudah menguji berbagai strategi untuk menekan waktu loading Next.js ke titik terendah. Hasilnya? Kami berhasil menurunkan waktu loading critical path hingga 40% di beberapa project migrasi besar. Dan kuncinya cuma satu: Lupakan cara kerja Pages Router yang lama dan peluk erat App Router.

App Router bukan sekadar update tampilan folder. Ini adalah pergeseran paradigma total yang didukung oleh React Server Components (RSC). Kalau kamu masih pakai Pages Router, atau baru migrasi tapi belum sepenuhnya memanfaatkan App Router, bersiaplah untuk pencerahan, karena inilah cara kami mengubah Next.js dari cepat menjadi kilat.

*

1. Fondasi Kecepatan: Memahami React Server Components (RSC)

Next.js 13 dan 14 (App Router) memperkenalkan konsep React Server Components. Ini adalah jurus rahasia yang bisa memangkas waktu loading drastis, hingga 40% yang kami janjikan itu.

Gini nih, biar lo nggak pusing: Di Pages Router, hampir semua komponen dianggap sebagai komponen klien secara default. Artinya, browser harus mengunduh, mem-parsing, dan menjalankan JavaScript untuk semua komponen itu—proses yang kita sebut hydration. Inilah biang keladi lambatnya Largest Contentful Paint (LCP) dan Total Blocking Time (TBT).

Dengan App Router, kebalikannya yang berlaku: Semua komponen secara default adalah Server Components.

Kenapa Server Components Itu Sakti?

  1. Zero Client-Side JavaScript: Komponen server di-render sepenuhnya di server. Yang dikirim ke browser hanyalah HTML dan referensi minimal untuk client components yang dibutuhkan. Ini artinya, bundle size JavaScript yang harus diunduh user turun drastis. Kalau Javapixa Creative Studio membuat landing page yang 90% isinya statis, maka 90% kode tersebut tidak perlu di-hydrate di browser.
  2. Data Fetching Lebih Cepat: Server Components bisa mengambil data (misalnya dari API atau database) langsung di server saat rendering. Nggak perlu lagi efek waterfall (nunggu komponen ke-render di klien, baru fetch data, baru render hasilnya). Semua data siap saat HTML dikirim.
  3. Mengurangi Hydration Cost: Dengan berkurangnya JS di sisi klien, proses hydration (proses React 'menghidupkan' HTML statis agar interaktif) jadi super cepat. Ini langsung menyerang TBT dan TTI.

Tips Praktis Javapixa: Gunakan Server Components untuk semua yang tidak memerlukan interaksi (menampilkan data, layout, header statis, footer, komponen navigasi tanpa state dinamis). Hanya tambahkan 'use client' jika komponen tersebut benar-benar butuh state, lifecycle effects (seperti useEffect), atau event listeners (seperti onClick).

*

2. Memutus Rantai Client Component dengan Strategi "Edge"

Kesalahan umum saat migrasi ke App Router adalah menaruh 'use client' di level atas (misalnya, di komponen layout besar) hanya karena ada satu tombol interaktif di dalamnya. Ini sama saja membatalkan semua keuntungan RSC.

Bayangkan kamu punya layout: Header, Sidebar, dan Content. Di Sidebar ada satu tombol 'Toggle Dark Mode' yang interaktif. Kalau kamu kasih 'use client' di komponen Sidebar, semua komponen statis di Sidebar (foto profil, list menu, dll.) akan diubah menjadi Client Component, memaksa browser mengunduh dan menghidrasi semuanya.

Strategi Smart Client Boundary

Di Javapixa Creative Studio, kami menggunakan strategi Client Boundary.

  1. Isolasi Interaksi: Identifikasi bagian terkecil yang butuh interaksi. Dalam contoh Sidebar tadi, yang interaktif hanya tombol 'Toggle Dark Mode'.
  2. Pindahkan 'use client': Buat komponen baru bernama DarkModeToggle.tsx dan letakkan 'use client' di situ. Komponen ini akan jadi yang paling ringan.
  3. Slotting dalam Server Component: Komponen Sidebar (induknya) tetap menjadi Server Component. Ia hanya mengimpor dan me-render DarkModeToggle.

Dengan cara ini, hanya chunk JS kecil (tombol toggle) yang dikirim ke klien, sementara sisa Sidebar tetap di-render di server. Dampaknya ke TBT? Kolaps! Ini adalah trik paling ampuh untuk menurunkan loading JS hingga 40%.

*

3. Mengoptimalkan Data Fetching Tingkat Lanjut

Di Next.js, kecepatan loading bukan cuma soal kode yang sedikit, tapi juga soal seberapa cepat data siap saat diminta. Next.js App Router (khususnya versi 14 ke atas) memberi kita alat caching yang super powerfull yang sering diabaikan.

A. Fetch dan Caching Otomatis

Lupakan useEffect untuk fetching data. Dalam Server Components, cukup gunakan fetch bawaan. Next.js secara otomatis akan:

  1. Deduping Requests: Jika kamu memanggil fetch dengan URL yang sama di berbagai komponen dalam satu render, Next.js hanya akan menjalankan satu kali request.
  2. Penyimpanan Cache Persistent: Hasil fetch akan otomatis disimpan di cache (mirip seperti getStaticProps tapi lebih granular). Kecuali kamu secara eksplisit meminta no-store atau mengatur revalidate time yang pendek, data akan disajikan sangat cepat dari cache Next.js.

Ini sangat berbeda dengan fetching di Pages Router yang seringkali memerlukan library tambahan (seperti SWR atau React Query) untuk manajemen cache yang kompleks. Di App Router, caching sudah jadi fitur built-in dan berjalan di server.

B. Server Actions untuk Mutasi Instan

Untuk operasi seperti mengirim form, update data, atau delete (operasi mutasi), hindari membuat API route handler terpisah yang harus dipanggil oleh fetch dari klien. Gunakan Server Actions.

Server Actions adalah fungsi asinkronus yang didefinisikan di server dan bisa dipanggil langsung dari komponen klien.

javascript
// Di komponen form (Client Component)
// 'use client'
import { submitForm } from '@/app/actions';
  
  Submit

Keuntungannya: Tidak ada network overhead* tambahan untuk mendefinisikan API endpoint. Data mutasi dan revalidation cache terjadi secara atomik* di server. Next.js menangani semua proses serialization* dan keamanan (CORS, CSRF protection) secara otomatis.

Dengan memindahkan logika mutasi ke Server Actions, kita mengurangi kode klien, mempercepat waktu tunggu respons, dan membuat interaksi terasa jauh lebih snappy.

*

4. Menguasai Seni Asset Optimization

Kode sudah ramping, data sudah cepat. Sekarang saatnya melihat aset yang seringkali jadi beban terberat: gambar, font, dan third-party scripts.

A. Next/Image Component: Bukan Hanya Komponen Biasa

Next.js memiliki komponen

yang jauh lebih baik daripada sekadar tag

biasa. Di Javapixa Creative Studio, penggunaan komponen ini wajib hukumnya, tapi ada beberapa trik agar ia maksimal:

  1. Priority Attribute: Next.js akan memprioritaskan loading gambar yang ada di above-the-fold (area yang terlihat pertama kali tanpa scroll) jika kamu menambahkan priority. Ini krusial untuk LCP.
  2. Format Modern: Pastikan image loader (default Vercel, atau custom seperti Cloudinary) di Next.js sudah mengkonversi gambar ke format modern seperti WebP atau AVIF. Format ini bisa memangkas ukuran file gambar hingga 30-50% tanpa penurunan kualitas yang signifikan.
  3. Lupakan fill kecuali Perlu: Penggunaan fill (membuat gambar mengisi seluruh parent) bisa menyebabkan isu CLS (Cumulative Layout Shift) jika tidak dikelola dengan baik. Selalu definisikan width dan height untuk menghindari CLS.

B. Font Loading Strategy

Font yang tidak di-load dengan benar seringkali menyebabkan flash of unstyled text (FOUT) atau layout shift yang mengganggu. Gunakan next/font bawaan Next.js.

javascript
import { Roboto } from 'next/font/google';

Dengan display: 'swap', browser akan segera menampilkan teks dengan font sistem, dan setelah font custom selesai diunduh, ia akan di-swap. Ini mencegah layar kosong saat menunggu font besar.

C. Menjinakkan Third-Party Scripts (Google Analytics, Iklan, Chatbots)

Script pihak ketiga (misalnya Google Tag Manager, Intercom Chat, atau Pixel Tracking) sering kali menjadi penyebab utama tingginya TBT dan lambatnya INP (Interaction to Next Paint).

Gunakan komponen