Web Worker - Tuong-Nguyen/Angular-D3-Cometd GitHub Wiki

1. definition

A web worker is a JavaScript that runs in the background, independently of other scripts, without affecting the performance of the page.

The worker thread can perform tasks without interfering with the user interface. You can run whatever code you like inside the worker thread.

Data is sent between workers and the main thread via a system of messages. Send data with postMessage() method and receive it by "onmessage" event handler.

2. browser support

wanna more? check here!

Check browser support the worker:

if (typeof(Worker) !== "undefined") {
    // Yes! Web worker support!
    // Some code.....
} else {
    // Oh Sorry bae..!
}

or

if(window.Worker){
    //Some code
}

3. types of web worker

There are two types of web worker. Dedicated and Shared worker.

A dedicated worker is only accessible from the script that first spawned it, whereas shared workers can be accessed from multiple scripts.

3.1 dedicated worker

  • initialization

var worker = new Worker('worker.js');
  • termination

worker.terminate();
//close();
  • demonstration

in index.html file:

//Check browser support
  if (typeof(Worker)==="undefined") {
     alert("Ops, your browser doesn't support HTML5 Web Worker! Please choose another modern browser and try again.");
  }
//Without web worker
  function nonWebWorker() {
    preStart();
    var a = [];

    for (var i = 500000; i >= 0; i--) {
      a.push(i);
    };

    function bubbleSort(a)
    {
      var swapped;
      do {
        swapped = false;
        for (var i=0; i < a.length-1; i++) {
          if (a[i] > a[i+1]) {
            var temp = a[i];
            a[i] = a[i+1];
            a[i+1] = temp;
            swapped = true;
          }
        }
      } while (swapped);
    }

    var start = new Date().getTime();
    bubbleSort(a);
    var end = new Date().getTime();
    var time = end - start;
    //Render progress bar
    afterStop(time);
  }

Without web worker, your browser maybe able to sort, your browser won't render anything until sorting ends,and you can't see the animated progress bar in the page.

//With web worker
  function withWebWorker() {
    preStart();
    //Initial // Dedicated Worker
    var worker = new Worker("worker.js");
    //Send data with postMessage() method
    worker.postMessage("start");
    //Receive data with onmessage event handler
    worker.onmessage = function(e) {
      //Render progress bar
      afterStop(e.data);
    };
    
  }

With web worker, you can see the animated progress bar in the page. Web worker run algorithm bubble sort in another thread so you can't see lagging or crash in a browser.

in worker.js file:

//Receive data
onmessage = function(e){
  if ( e.data === "start" ) {
    var array = [];

    //Initial
    for (var i = 50000000; i >= 0; i--) {
      array.push(i);
    };
    //Bubble sort the array
    function bubbleSort(array)
    {
      var swapped;
      do {
        swapped = false;
        for (var i=0; i < array.length-1; i++) {
          if (array[i] > array[i+1]) {
            var temp = array[i];
            array[i] = array[i+1];
            array[i+1] = temp;
            swapped = true;
          }
        }
      } while (swapped);
    }
    //Calculate time
    var start = new Date().getTime();
    bubbleSort(array);
    var end = new Date().getTime();
    var time = end - start;

    //Send data
    postMessage(time);
  }
};

3.2 shared worker

  • initialization

var worker = new SharedWorker('worker.js');

One big difference is that with a shared worker you have to communicate via a port object — an explicit port is opened that the scripts can use to communicate with the worker (this is done implicitly in the case of dedicated workers).

  • start

worker.port.start();  // called in parent thread
port.start();  // called in worker thread

When using the start() method to open the port connection, it needs to be called from both the parent thread and the worker thread if two-way communication is needed.

  • termination

worker.port.terminate();
//worker.port.close();
  • demonstration

in index.html file:

<!DOCTYPE html>
<html>
	<head>

	</head>
	<body>
		<h1>Hello Web Workers!</h1>
		<script>
			//Initial SharedWorker
			let worker = new SharedWorker('worker.js');
			//Start worker
			//With dedicated it work start implicit
			//With shared worker, u need to start worker explicit 
			worker.port.start();

			//Receive data
			worker.port.addEventListener('message', function (e) {
				console.log(e.data);
			});
			
		</script>
	</body>
</html>

in worker.js file:

let ports = [],
    i = 0;

this.addEventListener('connect', function (e) {
    let port = e.ports[0];
    ports.push(port);
    //Start port 

    //When using the start() method to open the port connection, 
    // it needs to be called from both the parent thread and the worker thread 
    // if two-way communication is needed.
    port.start();

    setInterval(function () {
        i++;
        ports.forEach(function (port) {
            //Send data back
            port.postMessage('Sending Message ' + i);
        });

        // if (i == 10) {
        //     this.close();
        // }
    }, 500);
});

**Note: ** To view Shared Worker, use chrome://inspect, choose Shared workers section.

**Note: ** To force stop Shared worker, choose shared worker in chrome://inspect and click terminate

3.3 functions and classes available to Web Workers

4. how to run demo

  • I use http-server of nodejs
  • Install nodejs (You can download it at https://nodejs.org). Install http-server by command npm install -g http-server
  • Go to folder demo worker, use command http-server to start the server. Generally, server is available on localhost:8080
⚠️ **GitHub.com Fallback** ⚠️