Web Workers in JavaScript
This article explains Web Workers in JavaScript.
YouTube Video
javascript-web-worker.html
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <title>JavaScript & 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 in JavaScript
Web Worker in JavaScript is a mechanism that allows code to run in a separate thread from the main thread. This allows heavy computations and long-running operations to be performed asynchronously, preventing the main thread from being blocked. By using Web Worker, the responsiveness of the user interface improves and the application's performance enhances.
The basic use of Web Worker
Let's take a look at the basic usage of Web Worker.
A new Web Worker is created by specifying a JavaScript file.
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};- This code demonstrates the basic mechanism of using a
Web Workerto request computation from the main thread and receive the result asynchronously. It sends10as a message to theWeb Workerand receives20as the result message. The main thread and theWeb Workercommunicate by sending and receiving messages to request and receive processing results.
Basic functions
Web Worker provides the following basic features.
postMessageandonmessageUsed to send and receive messages between the main thread and theWeb Worker. Send data withpostMessageand receive it withonmessage.- Thread Independence
Web Workeroperates completely independently of the main thread. Therefore, variables and functions defined in the main thread cannot be accessed. Required data needs to be passed viapostMessage. - Script Import
To load external scripts within a
Web Worker, useimportScripts().
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};Alternatively, you can also use import as shown below.
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};- By specifying
type: 'module'in the argument ofnew Worker, you can treat the worker as an ES module and use theimportsyntax.
Differences between Web Worker and async functions
Web Worker
Features
- Thread Isolation
Web Workerexecutes JavaScript code in a separate thread. This allows heavy calculation processing to be performed without blocking the main thread (UI thread). - Concurrent Processing
Using
Web Workerallows JavaScript programs to perform concurrent processing in multiple threads. - Message Communication
The
Web Workerand the main thread do not share data directly and exchange messages usingpostMessageandonmessage. - Cannot Access UI
Web Workercannot access the DOM, so it cannot directly manipulate the UI.
Use cases
- It is suitable for heavy computation processes such as image processing, data analysis, and encryption.
- It can be used when you do not want to block the main thread.
async
Features
- Simplifying Asynchronous Processing
The
asyncfunction is a syntax to make asynchronous processing more readable, internally usingPromise. - Single Thread
All
asyncfunctions run on the main thread. Therefore, you need to devise ways to avoid blocking the UI thread. - Optimal for I/O Operations It is suitable for asynchronous tasks such as network communication and file reading, but not for heavy computation.
Use cases
- It is suitable for network communication such as API calls.
- It is suitable for file reading and writing using browser APIs or Node.js.
Key Differences
| Features | Web Worker | async |
|---|---|---|
| Execution Environment | Separate thread | Main thread |
| Purpose | Parallel processing, offloading heavy computations | Concise description of asynchronous operations |
| DOM Access | Not possible | Possible |
| Communication Method | Message passing (e.g., postMessage) |
Not required (handled via direct function calls or await) |
| Use Cases | Time-consuming computations, data analysis | I/O operations, API calls |
When to Use Each
For CPU-intensive tasks, you can use Web Worker to reduce the load on the main thread. On the other hand, for network communication or I/O operations, you can simplify your code using async/await.
By combining both appropriately, you can achieve efficient asynchronous processing.
Examples of Web Worker Usage
Example of offloading heavy computation
Next is an example of offloading heavy computations.
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
- This code is an example of using a Web Worker to separate and execute heavy tasks like Fibonacci sequence calculations from the main thread.
An example of specifying a task name
Next is an example of sending and receiving messages by specifying a task name.
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 });- This code is an example of dispatching processing based on the
taskname in the message, with theWeb Workerreturning calculation results or errors to the main thread along with the task name.
Notes
When using Web Worker, keep the following points in mind.
- Cannot Access DOM
Web Workercannot manipulate the UI or access the DOM. DOM manipulation needs to be performed in the main thread. - Communication Overhead
There is some overhead when exchanging data between the main thread and the
Web Worker. This can affect performance, especially when exchanging large amounts of data frequently. - Same-Origin Policy
Web Workerscripts are subject to the same-origin policy. Scripts cannot be loaded from different domains.
Using Web Worker can improve the performance and responsiveness of your application, but it’s important to use it appropriately considering constraints such as the inability to manipulate the DOM.
You can follow along with the above article using Visual Studio Code on our YouTube channel. Please also check out the YouTube channel.