Cara Menggunakan Web Workers untuk Atasi Website Lemot Akibat Proses Berat
Pernahkah kamu mengunjungi sebuah website, lalu tiba-tiba layarnya membeku (freeze) dan tidak bisa diklik sama sekali? Kejadian seperti ini biasanya terjadi saat website sedang memproses data yang sangat besar di balik layar. Mulai dari mengolah file gambar berukuran jumbo, melakukan enkripsi data, hingga menghitung algoritma matematika yang rumit.
Secara default, JavaScript berjalan pada satu jalur utama yang disebut Main Thread. Jalur ini punya tanggung jawab yang sangat padat: mengurus tampilan (UI), menangani klik pengguna, mengatur animasi, hingga mengeksekusi logika kode. Ketika kamu memberikan tugas super berat ke Main Thread, jalur tersebut akan macet total. Akibatnya, website terasa patah-patah atau bahkan memunculkan peringatan Page Unresponsive.
Solusi terbaik untuk masalah ini adalah menyerahkan tugas berat tersebut kepada asisten khusus di balik layar. Di sinilah Web Workers mengambil peran. Fitur ini memungkinkan kamu memindahkan komputasi berat ke jalur terpisah (Background Thread), sehingga Main Thread tetap santai dan website kamu tetap responsif tanpa lag sedikit pun.
Kenapa Main Thread JavaScript Bisa Macet?
Untuk memahami mengapa Web Workers sangat kita butuhkan, kita harus tahu dulu cara kerja browser. JavaScript adalah bahasa pemrograman yang bersifat single-threaded. Artinya, JavaScript hanya bisa melakukan satu pekerjaan dalam satu waktu.
Bayangkan sebuah kasir di minimarket yang harus melayani antrean pelanggan. Jika ada satu pelanggan yang membawa barang belanjaan sangat banyak dan proses pembayarannya rumit, antrean di belakangnya pasti akan mengular dan macet. Kasir tersebut adalah Main Thread, dan pelanggan rumit itu adalah proses berat seperti pengolahan data.
Saat Main Thread sibuk menghitung ribuan data, browser tidak punya waktu untuk menggambar ulang layar (render) atau merespons ketukan jari pengguna. Web Workers hadir bagaikan membuka meja kasir baru yang khusus melayani pelanggan dengan belanjaan banyak, sehingga kasir utama bisa tetap fokus melayani antrean cepat.
Apa Itu Web Workers dan Bagaimana Cara Kerjanya?
Web Workers adalah fitur bawaan browser yang memungkinkan kita menjalankan kode JavaScript di latar belakang, terpisah dari thread utama halaman web. Karena berjalan di jalur yang berbeda, apa pun yang dilakukan oleh Web Worker tidak akan mengganggu performa visual website kamu.
Namun, karena jalurnya terpisah, Web Worker memiliki beberapa batasan ketat yang harus kamu ketahui:
- Tidak punya akses ke DOM: Kamu tidak bisa mengubah HTML secara langsung (misalnya lewat
document.getElementById) dari dalam Web Worker. - Tidak punya akses ke objek Window: Beberapa objek global seperti
window.alert()atauwindow.locationtidak tersedia. - Komunikasi lewat pesan: Main Thread dan Web Worker hanya bisa saling mengobrol menggunakan sistem pengiriman pesan (Message Passing).
Komunikasi antar-thread ini dilakukan menggunakan metode postMessage() untuk mengirim data, dan event listener onmessage untuk menerima data. Hubungan keduanya bisa digambarkan seperti dua orang yang saling berkirim surat.
Langkah Membuat Web Worker Pertama
Mari kita langsung praktik. Kita akan membuat sebuah simulasi sederhana: menghitung angka dari 1 sampai 1 miliar. Jika kita menjalankan ini di Main Thread, browser dipastikan akan langsung macet selama beberapa detik. Kita akan memindahkannya ke Web Worker.
1. Membuat File Main Thread (main.js)
Langkah pertama adalah membuat file JavaScript utama yang akan mendeteksi tombol klik dari pengguna dan menginisialisasi Web Worker.
// Memeriksa apakah browser mendukung Web Workers
if (window.Worker) {
// Membuat instance worker baru dengan menunjuk ke file worker.js
const MyWorker = new Worker('worker.js');
const tombolHitung = document.querySelector('#hitung-btn');
const areaHasil = document.querySelector('#hasil');
tombolHitung.addEventListener('click', () => {
areaHasil.textContent = "Sedang menghitung di background...";
// Mengirim perintah ke worker untuk mulai bekerja
MyWorker.postMessage('MULAI_HITUNG');
});
// Menerima hasil kalkulasi dari worker
MyWorker.onmessage = function(e) {
areaHasil.textContent = `Selesai! Hasilnya adalah: ${e.data}`;
};
} else {
console.log('Maaf, browser kamu tidak mendukung Web Workers.');
}
2. Membuat File Worker (worker.js)
Sekarang, kita buat file terpisah bernama worker.js. File inilah yang akan mengeksekusi proses perhitungan berat tanpa membebani tampilan website.
// Mendengarkan pesan dari Main Thread
onmessage = function(e) {
if (e.data === 'MULAI_HITUNG') {
let total = 0;
// Simulasi proses komputasi yang sangat berat
for (let i = 0; i < 1000000000; i++) {
total += i;
}
// Mengirimkan kembali hasil akhir ke Main Thread
postMessage(total);
}
};
Saat tombol diklik, pesan 'MULAI_HITUNG' dikirim ke worker.js. Selama proses perulangan 1 miliar kali berjalan, kamu masih bisa mengetik di kolom input, melakukan klik pada tombol lain, atau melihat animasi di website berjalan lancar tanpa hambatan.
Menangani Error di Dalam Web Workers
Sama seperti kode biasa, kode di dalam Web Worker juga bisa mengalami error. Karena worker berjalan di file terpisah, error yang terjadi di sana tidak akan muncul di konsol utama seperti biasanya secara otomatis jika tidak kita tangani.
Untuk menangkap error dari Web Worker, kita bisa memanfaatkan event listener onerror di file utama kita:
MyWorker.onerror = function(error) {
console.error(`Terjadi error di Worker: ${error.message} pada baris ${error.lineno} di file ${error.filename}`);
};
Dengan memasang pengaman ini, kamu bisa langsung tahu bagian mana dari kode background kamu yang bermasalah tanpa harus menebak-nebak.
Mematikan Web Worker Setelah Selesai Digunakan
Web Worker memakan resource memori komputer pengguna selama ia aktif. Jika tugasnya sudah benar-benar selesai dan tidak akan digunakan lagi dalam waktu dekat, sangat disarankan untuk mematikannya demi menghemat RAM.
Ada dua cara untuk menghentikan Web Worker:
- Dari Main Thread: Menggunakan perintah
.terminate().MyWorker.terminate(); // Worker langsung mati seketika - Dari Dalam Worker Sendiri: Menggunakan perintah
.close().close(); // Worker mematikan dirinya sendiri
Mengolah Gambar Ukuran Besar
Mari kita lihat skenario yang sering ditemukan di dunia nyata. Misalkan kamu membuat aplikasi web editor foto, dan kamu ingin menerapkan filter hitam-putih (grayscale) pada gambar beresolusi tinggi (misalnya 4K).
Mengubah warna setiap piksel pada gambar berukuran besar membutuhkan manipulasi array yang sangat panjang (ImageData). Jika dilakukan di Main Thread, transisi filter akan terasa patah-patah.
Berikut adalah cara memindahkannya ke Web Worker menggunakan transfer data berbasis array:
Kode di Main Thread (app.js)
const workerGambar = new Worker('image-worker.js');
function terapkanFilter(imageData) {
// Mengirim data piksel gambar ke worker
workerGambar.postMessage(imageData);
workerGambar.onmessage = function(e) {
const dataBaru = e.data;
// Tampilkan data gambar yang sudah difilter ke elemen canvas
konteksCanvas.putImageData(dataBaru, 0, 0);
console.log("Filter berhasil diterapkan tanpa lag!");
};
}
Kode di Worker (image-worker.js)
onmessage = function(e) {
const imageData = e.data;
const data = imageData.data;
// Lakukan perulangan untuk setiap piksel (RGBA)
for (let i = 0; i < data.length; i += 4) {
let brightness = 0.34 * data[i] + 0.5 * data[i + 1] + 0.16 * data[i + 2];
// Ubah nilai Red, Green, dan Blue menjadi sama untuk efek grayscale
data[i] = brightness; // Red
data[i + 1] = brightness; // Green
data[i + 2] = brightness; // Blue
}
// Kirim kembali data gambar yang sudah berubah
postMessage(imageData);
};
Kapan Harus Menggunakan Web Workers? (Dan Kapan Tidak Perlu)
Meskipun Web Workers terdengar sangat hebat, bukan berarti kamu harus memindahkan semua kode JavaScript kamu ke sana. Mengirim data antar-thread juga membutuhkan biaya performa (overhead) karena browser harus menyalin data tersebut.
Sebagai panduan praktis, berikut adalah tabel perbandingan untuk membantu kamu memutuskan:
| Gunakan Web Workers Jika... | JANGAN Gunakan Web Workers Jika... |
|---|---|
| Kamu mengolah file besar seperti CSV, JSON berukuran puluhan MB, atau memotong video/audio langsung di browser. | Kamu hanya melakukan request API standar (fetch atau axios). Browser sudah menangani ini secara asinkronus dengan baik. |
| Kamu melakukan manipulasi gambar tingkat lanjut di elemen HTML5 Canvas. | Kamu hanya perlu melakukan manipulasi DOM sederhana seperti memunculkan modal atau mengubah warna background halaman. |
| Aplikasi kamu menjalankan enkripsi data yang rumit (misalnya hashing password atau verifikasi kriptografi). | Aplikasi kamu berupa website blog atau company profile statis yang minim logika rumit. |
Kesimpulan
Web Workers adalah senjata rahasia bagi pengembang web untuk menciptakan pengalaman pengguna yang mulus dan tanpa hambatan. Dengan mendelegasikan tugas-tugas berat seperti kalkulasi matematika rumit dan pengolahan data besar ke latar belakang, website kamu akan tetap responsif dan bebas dari masalah UI freezing.
Kunci sukses dalam menggunakan Web Workers adalah tahu kapan harus menggunakannya. Gunakan secara bijak untuk komputasi berat yang memakan waktu lebih dari beberapa milidetik, dan pastikan untuk selalu menutup worker yang sudah tidak terpakai agar memori perangkat pengguna tetap hemat.
Daftar Referensi
Komentar