Web Worker dalam JavaScript

Web Worker dalam JavaScript

Artikel ini menjelaskan tentang Web Worker dalam JavaScript.

YouTube Video

javascript-web-worker.html
  1<!DOCTYPE html>
  2<html lang="en">
  3<head>
  4  <meta charset="UTF-8">
  5  <title>JavaScript &amp; HTML</title>
  6  <style>
  7    * {
  8        box-sizing: border-box;
  9    }
 10
 11    body {
 12        margin: 0;
 13        padding: 1em;
 14        padding-bottom: 10em;
 15        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
 16        background-color: #f7f9fc;
 17        color: #333;
 18        line-height: 1.6;
 19    }
 20
 21    .container {
 22        max-width: 800px;
 23        margin: 0 auto;
 24        padding: 1em;
 25        background-color: #ffffff;
 26        border: 1px solid #ccc;
 27        border-radius: 10px;
 28        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
 29    }
 30
 31    .container-flex {
 32        display: flex;
 33        flex-wrap: wrap;
 34        gap: 2em;
 35        max-width: 1000px;
 36        margin: 0 auto;
 37        padding: 1em;
 38        background-color: #ffffff;
 39        border: 1px solid #ccc;
 40        border-radius: 10px;
 41        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
 42    }
 43
 44    .left-column, .right-column {
 45        flex: 1 1 200px;
 46        min-width: 200px;
 47    }
 48
 49    h1, h2 {
 50        font-size: 1.2rem;
 51        color: #007bff;
 52        margin-top: 0.5em;
 53        margin-bottom: 0.5em;
 54        border-left: 5px solid #007bff;
 55        padding-left: 0.6em;
 56        background-color: #e9f2ff;
 57    }
 58
 59    button {
 60        display: block;
 61        margin: 1em auto;
 62        padding: 0.75em 1.5em;
 63        font-size: 1rem;
 64        background-color: #007bff;
 65        color: white;
 66        border: none;
 67        border-radius: 6px;
 68        cursor: pointer;
 69        transition: background-color 0.3s ease;
 70    }
 71
 72    button:hover {
 73        background-color: #0056b3;
 74    }
 75
 76    #output {
 77        margin-top: 1em;
 78        background-color: #1e1e1e;
 79        color: #0f0;
 80        padding: 1em;
 81        border-radius: 8px;
 82        min-height: 200px;
 83        font-family: Consolas, monospace;
 84        font-size: 0.95rem;
 85        overflow-y: auto;
 86        white-space: pre-wrap;
 87    }
 88
 89    .highlight {
 90        outline: 3px solid #ffc107; /* yellow border */
 91        background-color: #fff8e1;  /* soft yellow background */
 92        transition: background-color 0.3s ease, outline 0.3s ease;
 93    }
 94
 95    .active {
 96        background-color: #28a745; /* green background */
 97        color: #fff;
 98        box-shadow: 0 0 10px rgba(40, 167, 69, 0.5);
 99        transition: background-color 0.3s ease, box-shadow 0.3s ease;
100    }
101  </style>
102</head>
103<body>
104    <div class="container">
105        <h1>JavaScript Console</h1>
106        <button id="executeBtn">Execute</button>
107        <div id="output"></div>
108    </div>
109
110    <script>
111        // Override console.log to display messages in the #output element
112        (function () {
113            // Override console.log
114            const originalLog = console.log;
115            console.log = function (...args) {
116                originalLog.apply(console, args);
117                const message = document.createElement('div');
118                message.textContent = args.map(String).join(' ');
119                output.appendChild(message);
120            };
121
122            // Override console.error
123            const originalError = console.error;
124            console.error = function (...args) {
125                originalError.apply(console, args);
126                const message = document.createElement('div');
127                message.textContent = args.map(String).join(' ');
128                message.style.color = 'red'; // Color error messages red
129                output.appendChild(message);
130            };
131        })();
132
133        document.getElementById('executeBtn').addEventListener('click', () => {
134            // Prevent multiple loads
135            if (document.getElementById('externalScript')) return;
136
137            const script = document.createElement('script');
138            script.src = 'javascript-web-worker.js';
139            script.id = 'externalScript';
140            //script.onload = () => console.log('javascript-web-worker.js loaded and executed.');
141            //script.onerror = () => console.log('Failed to load javascript-web-worker.js.');
142            document.body.appendChild(script);
143        });
144    </script>
145</body>
146</html>

Web Worker di JavaScript

Web Worker dalam JavaScript adalah mekanisme yang memungkinkan kode berjalan pada thread terpisah dari thread utama. Ini memungkinkan perhitungan berat dan operasi yang berjalan lama dilakukan secara asinkron, mencegah thread utama menjadi terblokir. Dengan menggunakan Web Worker, responsivitas antarmuka pengguna meningkat dan kinerja aplikasi pun bertambah baik.

Penggunaan dasar Web Worker

Mari kita lihat penggunaan dasar dari Web Worker.

Web Worker baru dibuat dengan menentukan file JavaScript.

1// worker.js (created as a separate file)
2onmessage = function(event) {
3    // Receive a message
4    const data = event.data;
5    // Perform heavy computation or processing
6    const result = data * 2;
7    // Return the result to the main thread
8    postMessage(result);
9};
 1// Main thread (main.js)
 2const worker = new Worker('worker.js');
 3
 4// Send a message to the worker
 5worker.postMessage(10);
 6
 7// Receive a message from the worker
 8worker.onmessage = function(event) {
 9    console.log('Result from Worker: ', event.data); // Result: 20
10};
11
12// Error handling
13worker.onerror = function(error) {
14    console.error('Worker error: ', error);
15};
  • Kode ini menunjukkan mekanisme dasar penggunaan Web Worker untuk meminta komputasi dari thread utama dan menerima hasilnya secara asinkron. Kode tersebut mengirimkan 10 sebagai pesan ke Web Worker dan menerima 20 sebagai hasilnya. Thread utama dan Web Worker berkomunikasi dengan saling mengirim dan menerima pesan untuk meminta dan menerima hasil pemrosesan.

Fungsi dasar

Web Worker menyediakan fitur dasar berikut.

  • postMessage dan onmessage Digunakan untuk mengirim dan menerima pesan antara thread utama dan Web Worker. Kirim data dengan postMessage dan terima dengan onmessage.
  • Independensi Thread Web Worker berjalan secara mandiri dan terpisah dari thread utama. Oleh karena itu, variabel dan fungsi yang didefinisikan di thread utama tidak dapat diakses. Data yang diperlukan harus diteruskan melalui postMessage.
  • Import Skrip Untuk memuat skrip eksternal di dalam Web Worker, gunakan importScripts().
1// mathUtils.js
2function double(n) {
3    return n * 2;
4}
1// worker.js
2importScripts('mathUtils.js');
3
4onmessage = function(event) {
5    const input = event.data;
6    const result = double(input); // mathUtils.jsの関数を使用
7    postMessage(result);
8};
 1// Main thread (main.js)
 2const worker = new Worker('worker.js');
 3
 4// Send a message to the worker
 5worker.postMessage(10);
 6
 7// Receive a message from the worker
 8worker.onmessage = function(event) {
 9    console.log('Result from Worker: ', event.data); // Result: 20
10};
11
12// Error handling
13worker.onerror = function(error) {
14    console.error('Worker error: ', error);
15};

Sebagai alternatif, Anda juga dapat menggunakan import seperti di bawah ini.

1// lib.js
2
3// Simulated CPU-intensive task
4export function doHeavyWork(n) {
5    return n * 2;
6}
1// worker.js
2import { doHeavyWork } from './lib.js';
3
4self.onmessage = (event) => {
5  const data = event.data;
6  const result = doHeavyWork(data);
7  self.postMessage(result);
8};
 1// Main thread (main.js)
 2const worker = new Worker('worker.js', { type: 'module' });
 3
 4// Send a message to the worker
 5worker.postMessage(10);
 6
 7// Receive a message from the worker
 8worker.onmessage = function(event) {
 9    console.log('Result from Worker: ', event.data); // Result: 20
10};
11
12// Error handling
13worker.onerror = function(error) {
14    console.error('Worker error: ', error);
15};
  • Dengan menentukan type: 'module' pada argumen new Worker, Anda dapat memperlakukan worker sebagai modul ES dan menggunakan sintaks import.

Perbedaan antara Web Worker dan fungsi async

Web Worker

Fitur
  • Isolasi Thread Web Worker mengeksekusi kode JavaScript di thread yang terpisah. Ini memungkinkan pemrosesan perhitungan berat dilakukan tanpa menghambat thread utama (UI thread).
  • Pemrosesan Konkuren Menggunakan Web Worker memungkinkan program JavaScript melakukan pemrosesan secara konkuren di beberapa thread.
  • Komunikasi Pesan Web Worker dan thread utama tidak berbagi data secara langsung, melainkan bertukar pesan menggunakan postMessage dan onmessage.
  • Tidak Bisa Mengakses UI Web Worker tidak dapat mengakses DOM, sehingga tidak dapat memanipulasi UI secara langsung.
Kasus penggunaan
  • Cocok untuk proses perhitungan berat seperti pemrosesan gambar, analisis data, dan enkripsi.
  • Dapat digunakan ketika Anda tidak ingin menghambat thread utama.

async

Fitur
  • Menyederhanakan Pemrosesan Asinkron Fungsi async adalah sintaks untuk membuat pemrosesan asinkron menjadi lebih mudah dibaca, yang secara internal menggunakan Promise.
  • Single Thread Semua fungsi async dijalankan pada thread utama. Oleh karena itu, Anda perlu mencari cara untuk menghindari penghambatan thread UI.
  • Optimal untuk Operasi I/O Ini cocok untuk tugas-tugas asinkron seperti komunikasi jaringan dan pembacaan file, tetapi tidak untuk komputasi berat.
Kasus penggunaan
  • Ini cocok untuk komunikasi jaringan seperti pemanggilan API.
  • Ini cocok untuk pembacaan dan penulisan file dengan menggunakan API browser atau Node.js.

Perbedaan Utama

Fitur Web Worker async
Lingkungan Eksekusi Thread terpisah Thread utama
Tujuan Pemrosesan paralel, mengurangi beban komputasi berat Deskripsi ringkas tentang operasi asinkron
Akses DOM Tidak memungkinkan Memungkinkan
Metode Komunikasi Pertukaran pesan (mis., postMessage) Tidak diperlukan (ditangani melalui pemanggilan fungsi langsung atau await)
Kasus Penggunaan Komputasi yang memakan waktu, analisis data Operasi I/O, panggilan API

Kapan Menggunakan Masing-masing

Untuk tugas yang memerlukan banyak CPU, Anda dapat menggunakan Web Worker untuk mengurangi beban pada thread utama. Di sisi lain, untuk komunikasi jaringan atau operasi I/O, Anda dapat menyederhanakan kode Anda menggunakan async/await.

Dengan menggabungkan keduanya dengan tepat, Anda dapat mencapai pemrosesan asinkron yang efisien.

Contoh Penggunaan Web Worker

Contoh mengalihkan perhitungan berat

Berikutnya adalah contoh memindahkan komputasi berat.

 1// worker.js
 2onmessage = function(event) {
 3    const num = event.data;
 4    const result = fibonacci(num);
 5    postMessage(result);
 6};
 7
 8function fibonacci(n) {
 9    if (n <= 1) return n;
10    return fibonacci(n - 1) + fibonacci(n - 2);
11}
1// Main thread
2const worker = new Worker('worker.js');
3
4worker.onmessage = function(event) {
5    console.log('Fibonacci result: ', event.data);
6};
7
8worker.postMessage(40); // Delegate heavy computation to the worker
  • Kode ini adalah contoh penggunaan Web Worker untuk memisahkan dan menjalankan tugas berat seperti perhitungan deret Fibonacci dari thread utama.

Contoh penentuan nama task

Berikutnya adalah contoh pengiriman dan penerimaan pesan dengan menentukan nama task.

 1// worker.js
 2self.onmessage = function(event) {
 3    switch (event.data.task) {
 4        case 'add':
 5            const result = event.data.a + event.data.b;
 6            self.postMessage({ task: 'result', value: result });
 7            break;
 8        default:
 9            self.postMessage({ task: 'error', message: 'Invalid Task' });
10    }
11};
 1// Main thread
 2const worker = new Worker('worker.js');
 3
 4worker.onmessage = function(event) {
 5    switch (event.data.task) {
 6        case 'result':
 7            console.log('Task result: ', event.data.value);
 8            break;
 9        case 'error':
10            console.error('Error: ', event.data.message);
11            break;
12    }
13};
14
15worker.postMessage({ task: 'add', a: 10, b: 20 });
  • Kode ini merupakan contoh pengolahan berdasarkan nama task pada pesan, di mana Web Worker mengirimkan hasil perhitungan atau error ke thread utama beserta nama task-nya.

Catatan

Saat menggunakan Web Worker, perhatikan poin-poin berikut.

  • Tidak Bisa Mengakses DOM Web Worker tidak dapat memanipulasi UI atau mengakses DOM. Manipulasi DOM perlu dilakukan di thread utama.
  • Biaya Komunikasi Ada sedikit overhead saat bertukar data antara thread utama dan Web Worker. Ini dapat memengaruhi kinerja, terutama ketika sering bertukar data dalam jumlah besar.
  • Kebijakan Same-Origin Skrip Web Worker tunduk pada kebijakan same-origin. Skrip tidak dapat dimuat dari domain yang berbeda.

Menggunakan Web Worker dapat meningkatkan kinerja dan responsivitas aplikasi Anda, tetapi penting untuk menggunakannya secara tepat dengan mempertimbangkan keterbatasan seperti ketidakmampuan memanipulasi DOM.

Anda dapat mengikuti artikel di atas menggunakan Visual Studio Code di saluran YouTube kami. Silakan periksa juga saluran YouTube kami.

YouTube Video