Maximize web Performance: Overcome JavaScript Threading Limitations with Web Workers

Why?

Web Workers: A solution for overcoming JavaScript’s single-threaded limitations.

Running JavaScript tasks in background threads, separate from the main browser thread which is responsible for rendering the UI and handling user interactions.

So Its possible to run heavy task in multiple process and at the same time keep the ui responsive.

How?

The structure

Our Worker script (for example our-web-worker.js) A separate Script Which is responsible for maintaining the background task

Since the wokerscript runs seperately from our main website script so we need to set a communication between web-worker script and our main browser script.

postMessage: It used for send message in both sides. We can send instruction: the variable and other data to the worker script. and the worker script can send the result with it

onmessage: When one script( main script or worker script) postMessage other script get that message with onmessage.

Example

our-web-worker.js





self.onmessage = function(event) {
    const n = event.data;
    const result = calculateFibonacci(n);

    self.postMessage(result);
};

function calculateFibonacci(n) {
    var fib = [0, 1];
    for (let i = 2; i <= n; i++) {
        fib[i] = fib[i - 1] + fib[i - 2];
    }
    //return fib[n];
}




Our web-worker.html



<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Web Worker Example</title>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.5.0/semantic.min.css">
</head>
<body>
  <div class="ui container">
    <h2 class="ui header">Fibonacci Sequence Calculator</h2>
    <div class="ui action input">
      <input type="number" id="numberInput" placeholder="Enter a number...">
      <button class="ui button" onclick="calculateWithWorkers()">Calculate with Workers</button>
      <button class="ui button" onclick="calculateWithoutWorker()">Calculate without Worker</button>
    </div>
    <div id="resultWorkers" class="ui message hidden"></div>
    <div id="resultWithoutWorker" class="ui message hidden"></div>
  </div>

  <script>
    function calculateWithWorkers() {
      const number = parseInt(document.getElementById('numberInput').value);
      const startTime = performance.now();

      const workers = [];
      const workerResults = [];

      const numWorkers = 4;

      const range = Math.floor(number / numWorkers);

      for (let i = 0; i < numWorkers; i++) {
        const worker = new Worker('our-web-worker.js');

        worker.onmessage = function(event) {
          workerResults.push(event.data);

          if (workerResults.length === numWorkers) {
            const result = workerResults.reduce((acc, val) => acc + val, 0);
            displayResult('resultWorkers', result, startTime);
            workers.forEach(worker => worker.terminate());
          }
        };

        const start = i * range + 1;
        const end = (i + 1) * range;
        worker.postMessage({ start, end, number });
        
        workers.push(worker);
      }
    }

    function calculateWithoutWorker() {
      const number = parseInt(document.getElementById('numberInput').value);
      const startTime = performance.now();
      const result = calculateFibonacci(number);
      displayResult('resultWithoutWorker',result, startTime);
    }

    function calculateFibonacci(n) {
      var fib = [0, 1];
      for (let i = 2; i <= n; i++) {
        fib[i] = fib[i - 1] + fib[i - 2];
      }
      //return fib[n];
    }

    function displayResult(elementId, result='', startTime) {
      const resultElement = document.getElementById(elementId);
      const elapsedTime = (performance.now() - startTime).toFixed(2) + ' milliseconds';
      resultElement.classList.remove('hidden');
      resultElement.textContent = `Result: (Time taken: ${elapsedTime})`;
    }
  </script>
</body>
</html>




we applied 4 worker. To test the code run in a server.

If you test this directly in the browser you may face the security issue. To overcome this

setup a simple server for testing.

If you are on linux you can use python built in server

make sure terminal is open from your code directory.

python3 -m http.server

Then go to http://localhost:8000 and click on the web-worker.html

Try larger number for example 5 million to check the result in the user input. As we are testing the worker with Fibonacci number

Related Posts

How to get current time from browser in JavaScript
June 16, 2024

Current Time From Browser The current time is: We can get the current time with built- in JavaScript object Date To get the time we have to create the Date object first simply like this As we created the date object we can console.log to get the result We get the result like this. we […]

How to Make Analog Clock with HTML, CSS, and JavaScript
April 25, 2024

Simple Clock 12 3 6 9 The structure and the essentials So we just add this logic in the clock that’s it. We get the time from browser const now = new Date(); const hours = now.getHours(); const minutes = now.getMinutes(); const seconds = now.getSeconds(); Copy Code Then access the clock hand from JavaScript const […]