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 Worker
to request computation from the main thread and receive the result asynchronously. It sends10
as a message to theWeb Worker
and receives20
as the result message. The main thread and theWeb Worker
communicate by sending and receiving messages to request and receive processing results.
Basic functions
Web Worker
provides the following basic features.
postMessage
andonmessage
Used to send and receive messages between the main thread and theWeb Worker
. Send data withpostMessage
and receive it withonmessage
.- Thread Independence
Web Worker
operates 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 theimport
syntax.
Differences between Web Worker
and async
functions
Web Worker
Features
- Thread Isolation
Web Worker
executes 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 Worker
allows JavaScript programs to perform concurrent processing in multiple threads. - Message Communication
The
Web Worker
and the main thread do not share data directly and exchange messages usingpostMessage
andonmessage
. - Cannot Access UI
Web Worker
cannot 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
async
function is a syntax to make asynchronous processing more readable, internally usingPromise
. - Single Thread
All
async
functions 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
task
name in the message, with theWeb Worker
returning 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 Worker
cannot 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 Worker
scripts 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.