DEV Community

Cover image for ⚡ Understanding JavaScript Web Workers: Harnessing the Power of Multithreading
Ishraq Tanvir
Ishraq Tanvir

Posted on • Updated on • Originally published at Medium

⚡ Understanding JavaScript Web Workers: Harnessing the Power of Multithreading

Hello fellow developers! 🚀 If you’re on a quest to make your JavaScript code faster and more efficient, Web Workers might be your new best friend! Today, we're diving into a cool concept that’s like having a superhero sidekick for your web apps — Web Workers. Imagine having a helper who takes care of all the heavy lifting while you focus on the main stuff. That’s exactly what Web Workers can do!

It's like having a homemaker who takes care of the cleaning, cooking, and washing while you focus on what matters most...your code!

What Exactly Are Web Workers?

Think of Web Workers as your secret agents who run in the background, handling tasks like complex calculations or data processing without slowing down your main thread. This means your web app stays smooth and snappy, even when you’re dealing with heavy tasks.

Here’s a fun way to look at it:

JavaScript Web Workers

Why Bother with Web Workers?

JavaScript is single-threaded, which means it can only do one thing at a time. When you’re running a long task on the main thread, your web app can freeze or take a while to load, making users wait and possibly causing frustration. Web Workers come to the rescue by handling these tasks on a separate thread, so your app remains responsive. And users get happy with a faster application!

Let’s Be a Bit Practical!

We’ll break it down into a few simple steps so you can understand how it actually works!

Step 1: Creating the Worker Script

First up, we need a separate JavaScript file for our worker. Let’s call it worker.js or any name you choose!

worker.js:

self.onmessage = function (e) {
    const number = e.data;
    const result = fibonacci(number);
    postMessage(result);
};

function fibonacci(n) {
    if (n <= 1) return n;
    return fibonacci(n - 1) + fibonacci(n - 2);
}
Enter fullscreen mode Exit fullscreen mode

In this file, we set up our worker to listen for messages with self.onmessage, perform some heavy lifting (like calculating a Fibonacci number), and then send the result back with postMessage.

You might be wondering, what is self? Or what are postMessage and onmessage?

Web Workers operate in a different global context, not the familiar window. We call this special global context self!

Web Workers communicate with the main thread using events. By using events, they can send and receive messages or data. In the code, onmessage typically gets messages or data from the main thread, and postMessage sends processed data from the Web Worker back to the main thread.

Step 2: Creating and Talking to the Worker

Now, let’s see how to create a worker and send messages/data to it from our main script.

main.js:

// Create a new Web Worker using Worker()
const worker = new Worker('worker.js');

// Send data to the worker.
worker.postMessage(40); // Calculate the 40th Fibonacci number

// Receive data from the worker
worker.onmessage = function (e) {
    console.log('The result is:', e.data);
};

// Handle worker errors
worker.onerror = function (error) {
    console.error('Worker error:', error);
};
Enter fullscreen mode Exit fullscreen mode

Here, we create a new worker with new Worker('worker.js'), send a message to it with worker.postMessage, and get results with worker.onmessage. We also handle any potential errors with worker.onerror.

postMessage: sends data to the worker

onmessage: receives processed data from the worker

onerror: handles errors

Cool Ways to Use Web Workers

Web Workers can be super useful in a variety of scenarios. Let’s check out a couple of practical examples.

Example 1: Sorting a Massive Array

Sorting a huge array can take a lot of time. Let’s let a Web Worker handle that.

worker.js:

self.onmessage = function (e) {
    const array = e.data;
    array.sort((a, b) => a - b);
    postMessage(array);
};
Enter fullscreen mode Exit fullscreen mode

main.js:

const worker = new Worker('worker.js');

const largeArray = Array.from({ length: 1000000 }, () => Math.floor(Math.random() * 1000000)); // The array has been generated dynamically as it's a demo scenario.

worker.postMessage(largeArray);

worker.onmessage = function (e) {
    console.log('Sorted array:', e.data);
};
Enter fullscreen mode Exit fullscreen mode

In this example, we create a massive array of random numbers, send it to the worker for sorting, and then get the sorted array back.

Example 2: Fetching Data from an API

Web Workers can also handle API requests without blocking the main thread.

worker.js:

self.onmessage = async function (e) {
    const url = e.data;
    try {
        const response = await fetch(url);
        const data = await response.json();
        postMessage(data);
    } catch (error) {
        postMessage({ error: 'Failed to fetch data' });
    }
};
Enter fullscreen mode Exit fullscreen mode

main.js:

const worker = new Worker('worker.js');

worker.postMessage('https://api.example.com/data');

worker.onmessage = function (e) {
    if (e.data.error) {
        console.error(e.data.error);
    } else {
        console.log('Fetched data:', e.data);
    }
};
Enter fullscreen mode Exit fullscreen mode

Here, we send a URL to the worker, which fetches the data and sends it back. If something goes wrong, the worker sends an error message.

Best Practices for Web Workers

  • Keep Them Lightweight: Web Workers don’t have direct access to the DOM, so keep their tasks focused.
  • Efficient Messaging: Pass only essential data between the main thread and workers to avoid overhead.
  • Handle Errors: Always include error handling to catch any issues.

Visualizing Web Workers

Imagine Web Workers as a team of specialists in a factory. The main thread is the manager, and each worker handles different tasks.

JavaScript Web Workers

Each worker focuses on a specific task, keeping the main manager (thread) free to oversee the big picture.

Resources

For more detailed information about Web Workers, check out these resources:

Wrapping Up

Web Workers are like having a superpower in JavaScript. They let you offload heavy tasks to background threads, keeping your web apps fast and responsive. Next time your app seems to be lagging, remember your superhero sidekick—Web Workers are here to save the day!

Happy coding! 🌟

Top comments (0)