Skip to content

HTML Web Workers

Web Workers allow you to run JavaScript code in a background thread, preventing complex or long-running scripts from freezing the main browser interface.

Normally, JavaScript code runs in a single thread in the browser (the main thread). If a script takes a long time to execute (e.g., complex calculations, processing large amounts of data), it blocks the main thread. This makes the web page unresponsive – clicks don’t register, animations freeze, and the user experience suffers.

A Web Worker runs a script in a separate background thread. This allows the main thread to remain responsive, handling user interactions and UI updates, while the worker performs its task in the background.

Think of it like delegating a time-consuming task to an assistant, so you can continue with your main work without interruption.

Use cases include: image processing, data analysis, background data fetching/synchronization, complex calculations.

Web Workers are widely supported by all modern web browsers (Chrome, Firefox, Safari, Edge).

Using Web Workers involves three main steps:

Create a separate JavaScript file (e.g., my_worker.js) containing the code you want to run in the background.

Workers communicate with the main thread using the postMessage() method to send data back, and the onmessage event handler to receive data.

// Inside my_worker.js
console.log('Worker started');
// Listen for messages from the main thread
self.onmessage = function(event) {
console.log('Worker received:', event.data);
const number = event.data;
const result = number * 2; // Perform some task
// Send the result back to the main thread
self.postMessage(result);
};
// You can also send messages without waiting for one
// self.postMessage('Worker is ready!');

Note: self refers to the worker’s global scope.

In your main HTML page’s script, first check if the browser supports Workers. Then, create a new Worker object, passing the path to your worker script file.

// Inside main script (e.g., in <script> tag or main.js)
let myWorker;
if (window.Worker) { // Check for browser support
console.log('Worker support detected.');
myWorker = new Worker('my_worker.js');
// Add event listener to receive messages from the worker
myWorker.onmessage = function(event) {
console.log('Main thread received:', event.data);
// Update the UI or use the result
document.getElementById('result').textContent = `Result from worker: ${event.data}`;
};
// Optional: Handle errors from the worker
myWorker.onerror = function(error) {
console.error('Worker error:', error.message, error);
};
} else {
console.log('Web Workers not supported in this browser.');
document.getElementById('result').textContent = 'Web Workers not supported.';
}

3. Communicate (Send and Receive Messages):

Section titled “3. Communicate (Send and Receive Messages):”

Use worker.postMessage(data) in the main script to send data to the worker.

Use the worker.onmessage event handler in the main script to receive data from the worker.

// Example: Sending data to the worker after creation
if (myWorker) {
const valueToSend = 10;
console.log('Main thread sending:', valueToSend);
myWorker.postMessage(valueToSend);
}
// Result element in HTML:
// <p>Result: <output id="result">Waiting...</output></p>

Web Workers consume system resources. It’s important to terminate them when they are no longer needed to free up those resources.

Use the terminate() method on the worker object from the main script:

if (myWorker) {
myWorker.terminate();
myWorker = undefined; // Clean up the variable
console.log('Worker terminated.');
}

Workers can also close themselves using self.close() from within the worker script.

Because they run in a separate thread, Web Workers have limitations:

  • No Direct DOM Access: Workers cannot directly access or manipulate the HTML DOM (e.g., document object). They must communicate with the main thread via postMessage() to request UI updates.
  • Limited Access to window Object: They don’t have access to many properties of the window object (like window.alert). They do have access to some web APIs like fetch(), WebSocket, IndexedDB, and setTimeout/setInterval.
  • Cannot Access Parent Page Variables: They operate in their own scope and cannot directly access variables or functions from the script that created them.
  • Shared Workers: Can be accessed by multiple scripts (from the same origin), potentially running in different windows or iframes.
  • Service Workers: Act as proxy servers between the browser and the network. They enable features like offline caching, push notifications, and background sync, even when the page is not open. They have a different lifecycle and purpose than standard Web Workers.

For more details, check the MDN guide on Web Workers.