Home / Articles / Website Performance
Website Performance

Halaman Terlihat Sudah Jadi, tetapi Masih Lemot: Cara Memangkas JavaScript yang Menghambat Klik

Website bisa terlihat selesai dimuat, tetapi tetap terasa lambat saat pengguna membuka menu, mengisi formulir, atau menekan tombol. Sering kali masalahnya bukan server, melainkan JavaScript yang terlalu lama menguasai m…

Halaman Terlihat Sudah Jadi, tetapi Masih Lemot: Cara Memangkas JavaScript yang Menghambat Klik

Anda mungkin pernah membuka halaman yang tampak sudah selesai dimuat, tetapi tombolnya belum bisa ditekan. Menu tidak langsung terbuka, kolom pencarian terasa tertinggal, atau halaman seperti membeku sesaat setelah pengguna melakukan klik.

Masalah seperti ini sering berasal dari JavaScript yang bekerja terlalu lama di browser. Server boleh saja merespons cepat, tetapi jika browser masih sibuk menjalankan skrip, pengguna tetap merasakan website yang lambat.

Dalam pengukuran Core Web Vitals, masalah respons terhadap interaksi ini berkaitan dengan Interaction to Next Paint (INP). Sederhananya, INP melihat seberapa cepat halaman menampilkan perubahan setelah pengguna berinteraksi. Nilai yang baik berada di sekitar 200 milidetik atau kurang. Namun, angka bukan satu-satunya hal yang perlu dikejar: pengalaman nyata pengguna tetap menjadi ukuran paling penting.

JavaScript bisa membuat halaman “terkunci”

Browser memiliki bagian bernama main thread. Banyak pekerjaan penting berjalan di sini, termasuk membaca HTML dan CSS, menghitung tampilan, menjalankan JavaScript, serta memproses klik dan ketikan.

Main thread pada dasarnya mengerjakan satu tugas pada satu waktu. Jika sebuah tugas berjalan lebih dari 50 milidetik, tugas itu disebut long task. Selama tugas tersebut belum selesai, browser bisa menunda pemrosesan interaksi berikutnya.

Bayangkan kasir yang sedang menghitung satu transaksi besar. Walaupun pelanggan berikutnya sudah berdiri di depan meja, ia harus menunggu sampai perhitungan selesai. Memecah pekerjaan besar menjadi beberapa bagian kecil memberi kesempatan bagi kasir untuk melayani antrean di sela-selanya. Prinsipnya serupa pada browser.

Contoh penyebabnya cukup beragam:

  • File JavaScript terlalu besar dan memuat banyak fitur yang tidak langsung dibutuhkan.
  • Event handler melakukan terlalu banyak pekerjaan setelah tombol diklik.
  • Daftar produk atau komentar dirender sekaligus dalam jumlah besar.
  • Skrip analitik, iklan, chat widget, dan layanan pihak ketiga berjalan berulang-ulang.
  • Timer seperti setInterval() terus menjalankan pekerjaan berat di latar belakang.

Bedakan waktu muat dan waktu respons

Kesalahan yang sering terjadi adalah hanya menguji kecepatan halaman saat pertama dibuka. Padahal, website dapat memiliki halaman awal yang cepat tetapi interaksi yang lambat.

Misalnya, halaman toko online menampilkan daftar produk dengan cepat. Namun saat pengguna memilih filter harga, JavaScript membaca ribuan item, menyusun ulang DOM, menghitung layout, lalu memperbarui tampilan dalam satu proses panjang. Hasilnya: klik terasa tidak bekerja selama beberapa saat.

Karena itu, pengujian perlu mencakup tindakan yang benar-benar dilakukan pengguna: membuka menu, mengetik di pencarian, mengganti filter, membuka accordion, mengirim formulir, atau menambahkan barang ke keranjang.

Cara menemukan long task di Chrome DevTools

  1. Buka halaman yang ingin diuji di Chrome.
  2. Tekan F12 atau pilih Inspect, lalu buka panel Performance.
  3. Tekan tombol rekam, lakukan interaksi yang terasa lambat, kemudian hentikan rekaman.
  4. Cari bagian Main pada timeline. Task yang panjang biasanya ditandai indikator merah.
  5. Klik task tersebut dan periksa bagian Bottom-Up untuk melihat fungsi atau skrip yang paling banyak memakan waktu.

Jangan langsung menyimpulkan bahwa semua JavaScript harus dihapus. Yang perlu dicari adalah pekerjaan mana yang menghalangi respons pengguna dan apakah pekerjaan tersebut memang harus selesai saat itu juga.

Gunakan juga fitur Coverage untuk melihat kode JavaScript dan CSS yang dikirim tetapi tidak pernah digunakan pada halaman tersebut. Sering kali satu bundel besar dipakai untuk semua halaman, padahal halaman artikel hanya memerlukan sebagian kecil fiturnya.

Langkah pertama: kirim lebih sedikit JavaScript

Solusi paling aman biasanya bukan trik yang rumit, melainkan mengurangi pekerjaan sejak awal.

  • Pisahkan kode berdasarkan halaman atau fitur, bukan mengirim semua fungsi dalam satu bundel.
  • Tunda pemuatan chat widget, pelacakan tambahan, dan fitur yang tidak dibutuhkan pada tampilan pertama.
  • Gunakan defer atau strategi pemuatan yang sesuai untuk skrip yang tidak diperlukan sebelum halaman terlihat.
  • Hindari menjalankan kode inisialisasi besar hanya karena halaman baru saja dibuka.
  • Gunakan HTML dari server untuk konten utama jika tidak ada alasan kuat untuk membuat seluruh tampilan melalui JavaScript.

JavaScript yang lebih sedikit tidak otomatis menjamin website cepat, tetapi jumlah kode yang lebih kecil mengurangi pekerjaan parsing, kompilasi, dan eksekusi di browser.

Pecah pekerjaan besar menjadi beberapa bagian

Jika sebuah proses memang harus dilakukan, jangan selalu menjalankannya dalam satu blok panjang. Contohnya, daripada memproses 10.000 item sekaligus, kerjakan per 100 atau 200 item lalu beri kesempatan browser menangani interaksi dan rendering.

async function prosesBertahap(items) {
  for (let i = 0; i < items.length; i += 100) {
    const potongan = items.slice(i, i + 100);
    prosesPotongan(potongan);

    if (window.scheduler && scheduler.yield) {
      await scheduler.yield();
    } else {
      await new Promise(resolve => setTimeout(resolve, 0));
    }
  }
}

Contoh tersebut bukan resep yang harus ditempel di semua aplikasi. Ia hanya menunjukkan idenya: kerjakan sebagian, lalu yield atau mengembalikan kendali sementara ke browser. API scheduler.yield() dapat membantu pada browser yang mendukungnya, sedangkan setTimeout() bisa menjadi fallback sederhana.

Perhatikan bahwa memecah pekerjaan tidak mengurangi total pekerjaan secara ajaib. Tujuannya adalah mencegah satu pekerjaan panjang menghalangi klik, ketikan, animasi, atau pembaruan tampilan.

Periksa event handler dan timer

Event handler adalah fungsi yang berjalan ketika pengguna melakukan sesuatu, seperti klik atau mengetik. Fungsi ini sebaiknya segera memberi respons visual sederhana, lalu menunda pekerjaan berat yang tidak perlu dilakukan saat itu juga.

Contohnya, ketika pengguna mengetik di kotak pencarian, jangan langsung mengirim permintaan ke server untuk setiap karakter. Gunakan debounce agar pencarian baru dijalankan setelah pengguna berhenti mengetik sejenak. Jika permintaan lama tidak lagi relevan, pertimbangkan membatalkannya dengan AbortController.

Periksa pula setInterval(). Timer yang berjalan setiap beberapa detik dapat diam-diam mengganggu interaksi, terutama jika isinya melakukan pemindaian DOM, menghitung ulang data, atau mengirim banyak pekerjaan ke main thread.

Jangan lupakan skrip pihak ketiga

Skrip pihak ketiga sering dianggap berada di luar kendali, padahal dampaknya tetap dirasakan pengguna. Widget chat, iklan, heatmap, analitik, dan pemutar video dapat menambahkan pekerjaan baru ke halaman.

Uji halaman tanpa satu per satu layanan tersebut. Jika performa membaik secara signifikan, Anda memiliki petunjuk yang lebih jelas. Selanjutnya, tunda skrip sampai benar-benar dibutuhkan, batasi jumlah vendor, atau hapus layanan yang tidak menghasilkan manfaat sepadan.

Apa artinya bagi kita?

Website yang responsif bukan hanya website dengan waktu muat awal yang pendek. Pengguna juga perlu merasa bahwa kliknya diterima, ketikannya segera terlihat, dan halaman tidak membeku setelah interaksi.

Mulailah dari satu alur penting, misalnya pencarian produk atau pengiriman formulir. Rekam interaksinya di DevTools, cari long task, lalu perbaiki penyebab terbesar terlebih dahulu. Kurangi JavaScript yang tidak perlu, pecah proses berat, dan uji kembali pada perangkat atau jaringan yang lebih lambat.

Perbaikan kecil seperti menunda widget, mengurangi pekerjaan saat klik, atau merender daftar secara bertahap sering lebih berguna daripada langsung menambah server. Server yang cepat tetap penting, tetapi respons browser adalah bagian lain dari pengalaman website yang tidak boleh diabaikan.

Rujukan teknis: panduan web.dev tentang long tasks, panduan optimasi INP, dan dokumentasi Chrome tentang scheduler.yield().

Sumber & bacaan lebih lanjut

Jelajahi juga

– Rio Yotto @rioyotto