Pengalaman Kami Memeras Next.js Trik Supaya Bundle JavaScript Kamu Enggak Bikin Pusing

Next.js itu ibarat mobil sport. Cepat, powerful, dan basisnya sudah oke banget. Tapi, sebagus-bagusnya mobil sport, kalau bagasinya kamu isi batu, tentu larinya jadi lambat dan mesinnya teriak-teriak minta ampun. Nah, di dunia pengembangan website, "batu" itu seringkali adalah bundle JavaScript kita yang makin lama makin bengkak, alias bloated.

Kami di Javapixa Creative Studio, sebagai tim yang sehari-hari berkutat dengan performa kelas berat, sering banget ketemu client yang punya masalah klasik ini: website Next.js mereka lambat saat loading awal, padahal kodenya sudah terasa "bersih". Setelah diusut, ternyata biang keroknya cuma satu: ukuran bundle JavaScript yang kelewat batas.

Artikel ini bukan sekadar teori. Ini adalah pengalaman "memeras" Next.js, trik-trik yang kami aplikasikan untuk memastikan setiap project dari Javapixa tidak hanya cantik di depan, tapi juga ngebut di belakang layar. Siap-siap, karena kita akan bongkar rahasia optimasi performa yang mungkin belum kamu sadari.

Kenapa Ukuran Bundle Bikin Pusing Tujuh Keliling?

Sebelum masuk ke trik, kita harus sepakat dulu kenapa ukuran bundle itu masalah besar. Next.js menggunakan Webpack (atau Turbopack di versi terbaru) untuk menyatukan semua kode JavaScript, CSS, dan aset lainnya menjadi beberapa file yang dikirimkan ke browser pengguna.

Ketika file utama (main chunk) ukurannya mencapai 1MB, 2MB, bahkan lebih, ini yang terjadi:

  1. Waktu Download yang Lama: Terutama bagi pengguna dengan koneksi internet yang tidak stabil (misalnya, di kereta atau daerah pinggiran).
  2. Blokir Proses Utama (Main Thread Blocking): Browser harus mengunduh file tersebut, menganalisisnya, dan mengeksekusinya. Selama proses eksekusi ini, browser tidak bisa melakukan hal lain, termasuk merender tampilan, yang membuat website terlihat 'diam' atau janky.
  3. Core Web Vitals Hancur: Metrik seperti Largest Contentful Paint (LCP) dan First Input Delay (FID) langsung jeblok, yang artinya SEO website kamu juga ikut terancam. Google tidak suka website yang lelet.

Tujuan utama kita adalah: Mengirimkan hanya kode yang benar-benar dibutuhkan oleh pengguna pada saat itu juga. Tidak lebih, tidak kurang.

*

Trik #1: Dynamic Imports – Senjata Wajib Code Splitting

Next.js adalah framework yang secara default sudah melakukan Code Splitting per halaman. Artinya, kalau kamu mengakses /about, browser hanya akan mengunduh kode untuk halaman /about, bukan seluruh aplikasi. Ini bagus.

Namun, bagaimana jika di dalam halaman /home kamu punya sebuah komponen berat, misalnya library grafik 3D yang hanya muncul saat pengguna mengklik tombol? Jika kamu mengimpornya secara tradisional, komponen berat itu akan ikut masuk ke bundle /home, meskipun 99% pengguna mungkin tidak pernah mengkliknya.

Di sinilah Dynamic Imports menjadi pahlawan.

Teknik Dasar Menggunakan Dynamic

Daripada menggunakan import MyHeavyComponent from './MyHeavyComponent'; di bagian atas file, kita gunakan fungsi dynamic yang disediakan Next.js:

javascript
import dynamic from 'next/dynamic';const MyHeavyComponent = dynamic(() => import('../components/MyHeavyComponent'), {
  // Opsi fallback akan menampilkan loader saat komponen sedang diunduh
  loading: () => Sedang memuat grafik...,
  // Ini penting! Jika komponen ini hanya butuh di sisi client
  ssr: false, 
});

Kapan Dynamic Imports Wajib Digunakan?

Kami di Javapixa punya aturan emas:

  1. Komponen yang Berat (Berat di Dependencies): Contoh: Library visualisasi data (D3.js, Chart.js), editor teks kaya (Draft.js, TinyMCE), atau library animasi kompleks (Three.js).
  2. Komponen yang Jarang Dipakai: Modals, Pop-up, atau widget chat yang baru muncul setelah beberapa detik.
  3. Komponen di Bawah Lipatan (Below the Fold): Bagian yang baru terlihat setelah user melakukan scroll ke bawah.

Dengan Dynamic Imports, kita memastikan bahwa browser hanya akan mengunduh chunk JavaScript komponen berat itu setelah komponen tersebut dipanggil, atau saat halaman sudah selesai dimuat. Hasilnya? Initial Load Time turun drastis.

*

Trik #2: Mengaudit Dependensi – Jajan Mahal yang Harus Dipangkas

Sering kali, bundle kita bengkak bukan karena kode kita sendiri, melainkan karena library pihak ketiga yang kita install tanpa sadar betapa rakusnya mereka terhadap ukuran bundle.

Misalnya, kita hanya butuh satu fungsi kecil dari sebuah library, tapi kita mengimpor seluruh library-nya yang ukurannya bisa sampai ratusan KB.

Kenali dan Ganti Pelaku Utama

Ada beberapa library terkenal yang dulunya standar, tapi sekarang wajib diganti karena ukurannya yang besar:

A. Moment.js (Sang Raja Bloat)

Moment.js sangat populer untuk manipulasi tanggal, tapi ukurannya sangat besar, terutama karena dia membawa semua locale (semua bahasa) ke dalam bundle kamu, padahal mungkin kamu hanya pakai Bahasa Indonesia dan Inggris.

Solusi Kami: Ganti segera ke date-fns atau luxon. Keduanya jauh lebih modular dan mendukung tree shaking yang lebih baik, memastikan kamu hanya mengimpor fungsi yang benar-benar kamu gunakan.

B. Lodash atau Underscore

Sama seperti Moment.js, Lodash adalah library utilitas yang sangat berguna. Tapi, jika kamu mengimpornya dengan cara lama (import _ from 'lodash';), kamu mengimpor semua fungsi yang ada.

Solusi Kami: Selalu gunakan import spesifik.

Hindari:

javascript
import { find, map } from 'lodash'; 
// Seringkali ini masih menarik seluruh library kalau tidak dikonfigurasi dengan baik.

Gunakan:

javascript
import find from 'lodash/find';
import map from 'lodash/map'; 
// Atau jika menggunakan ES modules yang di-support build tool modern:
import { find, map } from 'lodash-es';

Ini memastikan bundler hanya memasukkan fungsi find dan map, bukan ratusan fungsi lainnya yang tidak terpakai.

*

Trik #3: Memaksimalkan Tree Shaking

Tree Shaking adalah proses eliminasi dead code (kode mati). Bayangkan pohon yang daunnya sudah layu dan harus digugurkan agar pohonnya tetap sehat. Next.js dan Webpack modern seharusnya sudah melakukan ini secara otomatis. Tapi, kita bisa membantu mereka bekerja lebih optimal.

Gunakan ES Modules (ESM)

Ini adalah prinsip dasar. Agar tree shaking bekerja, bundler harus tahu persis bagian mana dari library yang kamu pakai. Struktur ES Modules (import/export) memungkinkan hal ini, berbeda dengan CommonJS (require).

Pastikan saat kamu menginstal library, mereka mendukung ES Modules. Kebanyakan library modern sudah melakukannya, tapi jika kamu menggunakan library yang sudah tua, cek dokumentasinya atau cari alternatif modern.

Hindari Side Effects Tidak Terduga

Beberapa library lama memiliki side effects global (mengubah objek global saat di-import). Jika library memiliki side effects, bundler akan ragu untuk menghapusnya (menganggapnya sebagai code penting), meskipun kamu tidak menggunakan fungsi di dalamnya.

Di file package.json kamu, pastikan library yang kamu buat (jika kamu membuat library lokal) menyertakan flag ini agar Webpack tahu library tersebut aman di-shake:

json
// package.json 
{
  "sideEffects": false
}

*

Trik #4: Mengintip Isi Koper dengan Webpack Bundle Analyzer

Bagaimana kita tahu trik-trik di atas benar-benar bekerja? Kita tidak bisa sekadar menerka-nerka. Kita butuh bukti visual.

Ini adalah alat paling penting yang kami gunakan di Javapixa untuk diagnosis: @next/bundle-analyzer.

Cara Pasang Analyzer

  1. Install:
bash
    npm install --save-dev @next/bundle-analyzer
  1. Konfigurasi next.config.js:

Ubah file konfigurasi Next.js kamu menjadi seperti ini:

javascript
    // next.config.js
    const withBundleAnalyzer = require('@next/bundle-analyzer')({
      enabled: process.env.ANALYZE === 'true',
    });
  1. Jalankan Analisis:
bash
    ANALYZE=true npm run build

Setelah proses build selesai, browser kamu akan otomatis terbuka dan menampilkan visualisasi yang luar biasa: peta interaktif dari semua bundle kamu.

Membaca Peta Analisis

Peta ini menunjukkan kotak-kotak. Setiap kotak adalah sebuah file atau module. Ukuran kotak tersebut mencerminkan ukuran file di bundle kamu.

Apa yang harus kamu cari?

Kotak Besar yang Mencurigakan: Jika ada sebuah kotak besar di bundle utama (main chunk) yang ternyata isinya library yang jarang kamu pakai (misalnya library* grafik), itu adalah target utama Dynamic Import. Duplikasi: Kadang-kadang kamu melihat library yang sama muncul di dua chunk yang berbeda. Ini bisa jadi karena versi yang berbeda terinstal atau ada masalah import* yang tidak bersih.

Dengan alat ini, pekerjaan optimasi dari Javapixa Creative Studio menjadi sangat terukur. Kita tidak lagi menebak, tapi tahu pasti "berat" kode itu datang dari mana.

*

Trik #5: Optimasi Aset Non-JS (next/image dan next/font)

Meskipun fokus kita adalah JavaScript, seringkali loading aset lain yang lambat membuat browser sibuk, sehingga proses eksekusi JS tertunda. Next.js sudah menyediakan solusi superior untuk ini.

Next/Image: Sang Penyelamat Performance

Jangan pernah lagi menggunakan tag

HTML biasa di project Next.js. Selalu gunakan komponen next/image.

Kenapa?

  1. Automatic Resizing: Komponen ini akan menyesuaikan ukuran gambar berdasarkan ukuran layar perangkat pengguna, jadi pengguna mobile tidak perlu mengunduh gambar 4K yang besar.
  2. Lazy Loading Default: Gambar yang berada di luar tampilan awal (viewport) akan di-load belakangan.
  3. Modern Format: Otomatis menyajikan gambar dalam format modern seperti WebP atau AVIF jika browser mendukungnya.

Mengganti semua

dengan

mungkin terasa sepele, tapi ini adalah salah satu quick win terbesar dalam meningkatkan overall performance aplikasi.

Next/Font: Bye-bye Font Download Blocking

Di Next.js 13 ke atas, mereka memperkenalkan next/font. Ini adalah langkah maju yang menghilangkan kebutuhan untuk mengunduh file font secara manual atau menggunakan font pihak ketiga yang bisa memblokir rendering.

next/font secara otomatis mengoptimalkan font, mengurangi layout shift (Cumulative Layout Shift/CLS), dan meningkatkan kecepatan loading teks. Selalu gunakan ini untuk font Google atau font lokal.

*

Trik #6: Memanfaatkan Built-in Features (Transpilation & Compiler)

Next.js terus berevolusi. Di versi terbaru (13/14), mereka mengadopsi Rust-based compiler (SWC) yang jauh lebih cepat daripada Babel tradisional.

Minimisasi dan Kompresi

Secara default, Next.js sudah melakukan:

  1. Minimisasi: Menghapus spasi, komentar, dan menyingkat nama variabel dalam kode JS (mengurangi ukuran file).
  2. Gzip/Brotli Compression: Next.js server akan mengkompresi file yang dikirimkan ke browser.

Namun, jika kamu menggunakan server kustom (misalnya, server Node.js buatan sendiri, bukan Vercel atau Next.js server bawaan), pastikan kamu sudah mengaktifkan compression (compression middleware di Express) agar bundle yang dikirimkan ke pengguna ukurannya benar-benar kecil. Ini adalah langkah deployment yang krusial.

Mengoptimasi Next.js hingga bundle-nya kurus kerempeng bukanlah sihir, melainkan gabungan dari disiplin teknis dan penggunaan alat analisis yang tepat. Kunci utamanya adalah: jadikan Dynamic Imports sebagai kebiasaan, bersihkan dependensi yang tidak perlu, dan gunakan alat bawaan Next.js sebaik mungkin.

Di Javapixa Creative Studio, kami percaya bahwa website cepat bukan hanya nice-to-have, tapi adalah kewajiban. Performanya harus optimal, responsif, dan siap menghadapi jutaan traffic tanpa tersendat. Kami memastikan setiap detail kecil—mulai dari cara kita mengimpor library hingga konfigurasi bundler—sudah dioptimalkan untuk performa tertinggi.

Jika kamu atau bisnismu membutuhkan website atau aplikasi yang tidak hanya indah secara desain, tetapi juga memiliki fondasi teknis secepat kilat, kami di Javapixa Creative Studio siap menjadi rekan strategismu. Biarkan kami yang pusing memeras bundle JavaScript, agar kamu bisa fokus pada pertumbuhan bisnismu.