Web Workers in Javascript

Web workers are giving us the possibility to write multi-threaded Javascript, which does not block the DOM. Even the Asynchronous operations block the DOM to some extent. On the other side, web workers help us solve this problem, escaping the single-threaded environment and reaching a higher performance of our web pages.

In order to use:



  • Web workers live in their own file (Not interacting with the User Interface)
  • Functions are Passed By Copy
  • No global variables are allowed
  • Implementing Web Workers

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    /* -----------------------------Index.JS--------------------------*/
      
      // Check if web worker functionality is available for the browser
            if(window.Worker){
              
                // Creating new web worker using constructor
                var worker = new Worker('worker.js');
                  
                  
                var message = 'Hello';
              
                // Sending the message using postMessage
                worker.postMessage(message);
                  
                // On response
                worker.onmessage = function(e) {
                    console.log(e.data);
                };
              
            }
      
      
    /* -----------------------------Worker.JS--------------------------*/
      
    // Waits for any activity from the page
    self.onmessage = function(e) {
        if(e.data !== undefined) {
            // Do work 
            var total = e.data + ' World';
            // Posting back to the page
            self.postMessage(total)
        }
    }
    // Terminate with: worker.terminate()

    chevron_right

    
    

    In the example above, the worker is doing the work of concatenating the received string with the defined one and sends it back to the main.js file without interrupting the page.

    Output :'Hello World'
    

    Web Workers does not have access to:

  • The Parent Object
  • The Window Object
  • The Document Object
  • The DOM
  • However, the do have access to:

  • The location object
  • The navigator object
  • XMLHttpRequest
  • The Application Cache
  • Spawning other web workers (Stored at the same origin as the parent page)
  • Importing external script using importScripts()
  • Common use cases:

  • When complex computing calculations are required
  • In HTML5 Games (Higher frame rate)
  • At any websites containing JavaScript for performance improvement

  • Real World Example

    The following program is written for the reason to show what difference is in the behavior of our page with and without worker.

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    /* -----------------------------Index.JS--------------------------*/
    const delay = 5000;
      
    // Get element of without worker button
    const noWorkerBtn = document.getElementById('worker--without');
    // Add event listener to the button itself
    noWorkerBtn.addEventListener('click', () => {
        // Define the starting time
        const start = performance.now();
        // Do complex calculations
        while (performance.now() - start < delay);
        // Get the ending time
        const end = performance.now();
        // Calculate the difference in time
        const resWithoutWorker = end - start;
        // Log the result
        console.log('No worker:', resWithoutWorker);
          
    });
      
    // Define a worker
    const worker = new Worker('./worker.js');
      
    // Get element of with worker button
    const workerBtn = document.getElementById('worker--with');
      
    // Add event listener to the button
    workerBtn.addEventListener('click', () => {
        // Send delay number
        worker.postMessage(delay);
          
    });
    // On message from worker
    worker.onmessage = e => {
        // Log the result
        console.log("With worker: ", e.data);
    };
      
    /* -----------------------------Worker.JS--------------------------*/
      
    // On message received
    this.onmessage = e => {
        // Delay equals to data received
        const delay = e.data;
        // Define starting time
        const start = performance.now();
        // Do the complex calculation
        while (performance.now() - start < delay);
        // Get ending time
        const end = performance.now();
        // Calculate difference
        const resWithWorker = end - start;
        // Send result
        this.postMessage(end - start);
    };

    chevron_right

    
    

    Examples:

    Output: 'No worker: 5000'
    Output: 'With worker:  5000'
    

    That’s how the page behaves without our worker code:

  • The animation freezes because the JavaScript is blocking the DOM.
  • Complex Calculation Without a Web Worker

    Page behaviour without webworker

    That’s how the page behaves with our worker code:

  • As you can see the animation in the background is not interrupted as our worker does the calculation for us. In this way, we let the DOM thread run independently.
  • Complex Calculation with a Web Worker

    Page behaviour with webworker



    My Personal Notes arrow_drop_up

    Vice-President at the Computing Society of Edinburgh Napier University

    If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

    Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.