Mengapa Aplikasi Web Melambat Seiring Bertambahnya Data
Aplikasi yang gesit saat diluncurkan bisa menjadi lambat setahun kemudian. Penyebabnya biasanya sama, dan bisa dicegah sejak awal.
Pola ini berulang di banyak proyek: aplikasi terasa cepat saat pertama diluncurkan, lalu setahun kemudian pengguna mulai mengeluh halaman terlalu lama dimuat. Kodenya tidak berubah — yang berubah adalah jumlah datanya.
Penyebab paling umum: query N+1
Ini penyebab nomor satu yang kami temukan saat audit performa. Aplikasi mengambil daftar berisi 50 pesanan, lalu untuk setiap pesanan mengambil data pelanggannya satu per satu. Alih-alih satu query, database menerima 51 query.
Saat pengujian dengan sepuluh data, tidak ada yang terasa. Dengan ribuan data dan puluhan pengguna bersamaan, dampaknya nyata.
Di Laravel, perbaikannya sesederhana memuat relasi di awal:
// Memicu query tambahan untuk setiap pesanan
$orders = Order::latest()->take(50)->get();
// Cukup dua query untuk seluruh data
$orders = Order::with('customer')->latest()->take(50)->get();
Gunakan Laravel Debugbar atau DB::listen() pada tahap pengembangan untuk melihat jumlah query yang benar-benar dijalankan setiap halaman.
Indeks database yang belum ada
Kolom yang sering dipakai untuk menyaring atau mengurutkan data perlu indeks. Tanpa indeks, database memeriksa seluruh baris satu per satu.
Perhatikan kolom yang muncul di klausa where, order by, dan kolom foreign key. Jika sebuah query kerap menyaring berdasarkan dua kolom sekaligus, indeks gabungan biasanya lebih efektif daripada dua indeks terpisah.
Jalankan EXPLAIN pada query yang lambat untuk memastikan indeks benar-benar terpakai.
Memuat seluruh data sekaligus
Halaman yang menampilkan semua data tanpa pagination akan bekerja baik di awal dan menjadi tidak terpakai belakangan. Terapkan pagination sejak awal, bahkan ketika datanya masih sedikit.
Untuk data yang sangat besar, pagination berbasis kursor lebih efisien daripada berbasis nomor halaman, karena database tidak perlu melewati baris-baris sebelumnya.
Caching di lapisan yang tepat
Tidak semua data perlu diambil ulang setiap request. Daftar kategori, menu navigasi, dan pengaturan situs jarang berubah namun dibaca di hampir setiap halaman — semuanya kandidat baik untuk cache.
Yang penting adalah strategi invalidasi: cache harus dibuang ketika data sumbernya berubah, agar pengguna tidak melihat informasi usang.
Gambar yang tidak dioptimalkan
Sering kali penyebab halaman berat bukan database, melainkan gambar berukuran beberapa megabita yang ditampilkan kecil di layar. Sajikan gambar dalam ukuran yang sesuai, gunakan format modern seperti WebP, dan terapkan loading="lazy" untuk gambar di bawah area yang langsung terlihat.
Ukur, jangan menebak
Sebelum melakukan optimasi, pastikan Anda tahu bagian mana yang benar-benar lambat. Waktu yang dihabiskan mempercepat bagian yang sudah cepat tidak memberi manfaat apa pun bagi pengguna.