Let’s look at a couple of examples
This example is done by showing the earth’s seismic zones through red dots, The data is taken from the Geological Survey through console.log to see how long it takes to calculate the data. No Webworker No Web workers – all on main thread Use One webworker Two Web workers Use Eight Eight Web workers use 20 20 Web workers
Verdict: Yes? // Keep thinking
background
JavaScript
The engine runs single-threaded,JavaScript
In the time consumingI/O
Operations are handled as asynchronous operations, including keyboard and mouse operationsI/O
Input and output events, window sizeresize
Events, timers (SetTimeout and setInterval
) events,Ajax
Request networkI/O
The callback, and so on. When these asynchronous tasks occur, they will be placed in the browser’s event task queue, untilJavaScript
The run-time execution is executed on a first-in-first-out basis only when the execution thread is idle, but it is still single-threaded.
Although JS runs in a browser, it is single-threaded, one JS thread per window, but browsers are not single-threaded, such as Webkit or Gecko engines, may have the following threads:
Javascript engine threadsInterface render thread Browser events trigger thread Http request threadCopy the code
Many people think that async (promise async/await) is sufficient for ordinary work through similar event loops. However, if complex operations are performed, the deficiencies of these asynchronous pseudo-threads will gradually be shown. For example, setTimeout gets incorrect values. In addition, if the page has complex computation, it is easy to trigger the suspended animation state. In order to have multithreading function, Webworker was born. However, this does not mean that the JavaScript language itself supports multithreading. For the JavaScript language itself, it still runs on a single thread. Web Worker is just a capability/API provided by the browser (host environment).
Introduction to the
Web workers are part of the HTML5 standard, which defines a set of apis that allow a JavaScript program to run in a thread other than the main thread. Worker thread allows developers to write background programs that can run for a long time without being interrupted by users to execute transactions or logic, and at the same time ensure timely response of the page to users. Some large amounts of calculating code can be handed over to The Web worker to run without freezing the user interface. Cases will be introduced later
type
Web workers can be divided into two types: dedicated thread Dedicated Web worker and shared thread shared Web worker. The Dedicated Web worker ends when the current page closes; This means that a Dedicated Web worker can only be accessed by the page that created it. The corresponding Shared Web worker can be accessed by multiple pages. In Javascript code, the “Work” type represents a Dedicated Web worker, while the “SharedWorker” type represents a Shared Web worker. Shared workers can be Shared by multiple pages (in the same domain)
How to create
Web workers are created in the main thread by passing in the URL of the file. As follows:
let webworker = new Worker('myworker.js');Copy the code
The webworker instance object is returned, which acts as a bridge between the main thread and other threads
onmessage:Listen for an eventpostmessage:Send eventCopy the code
The relevant API for communication case code is as follows
// main thread main.js
var worker = new Worker("worker.js");
worker.onmessage = function(event){
The main thread receives a message from the child thread
};
// The main thread sends messages to child threads
worker.postMessage({
type: "start",
value: 12345
});
//web worker.js
onmessage = function(event){
/ / received
};
postMessage({
type: "debug",
message: "Starting processing..."
});Copy the code
The demo
How to terminate
If at some point we do not want the Worker to continue running, we need to terminate the thread by calling terminate on the main thread of the Worker or close on the corresponding thread:
// mode one main.js stops in the main thread
var worker = new Worker('./worker.js');
.
worker.terminate();
// Worker.js
self.close()Copy the code
The error mechanism
The onError API is provided
worker.addEventListener('error'.function (e) {
console.log('MAIN: '.'ERROR', e);
console.log('filename:' + e.filename + '-message:' + e.message + '-lineno:' + e.lineno);
});
// event.filename: the name of the Worker script that caused the error;
// event.message: error message;
// event.lineno: error line number;Copy the code
sharedWorker
For Web workers, a TAB page can only correspond to one Worker thread, which is independent of each other. And SharedWorker provides the ability to let pages in different tags share the same Worker script thread; And, of course, one important constraint is that they have to satisfy the same origin policy, that is, they have to be in the same domain; Instantiate Worker threads in pages (multiple) :
// main.js
var myWorker = new SharedWorker("worker.js");
myWorker.port.start();
myWorker.port.postMessage("hello, I'm main");
myWorker.port.onmessage = function(e) {
console.log('Message received from worker');
}Copy the code
// worker.js
onconnect = function(e) {
var port = e.ports[0];
port.addEventListener('message'.function(e) {
var workerResult = 'Result: ' + (e.data[0]);
port.postMessage(workerResult);
});
port.start();
}Copy the code
The online demo
Father and son thread
Create a thread within a thread
Context and scope
There is no window global object in the running environment of Worker threads, nor can they access DOM objects, so generally they can only perform pure JavaScript computations. However, he can still get the API provided by some browsers:
SetTimeout (), clearTimeout(), setInterval(), clearInterval() : With a function designed, the Worker can be created again in Worker: thread; XMLHttpRequest: object: means we can execute ajax requests in Worker threads; Navigator object: ppName, appVersion, Platform, userAgent and other information can be obtained; Location object (read only) : Gets information about the current URL; Application Cache indexedDB WebSocket, Promise,
Libraries or external scripts are introduced and accessed
In threads, the importScripts method is provided. If importScripts is used in a thread, follow these steps to resolve it
1Parse each parameter of the importScripts method.2If there are any failures or errors, throw a SYNTAX_ERR exception.3, try to get the script resource from the URL resource location provided by the user.4For each parameter of the importScripts method, obtain script resources in the order provided by the user and proceed with other operations.Copy the code
// worker.js
importScripts('math_utilities.js');
onmessage = function (event)
{
var first=event.data.first;
var second=event.data.second;
calculate(first,second); Calculate is a method in math_utilities.js
};
Copy the code
You can also introduce more than one at a time
// Can pass more than one time
importScripts('script1.js'.'script2.js');Copy the code
XMLHttpRequest
onmessage = function(evt){
var xhr = new XMLHttpRequest();
xhr.open("GET"."serviceUrl"); Xhr.onload = function(){postMessage(xhr.responsetext); }; xhr.send(); }Copy the code
jsonp
/ / set the json
function MakeServerRequest(a)
{
importScripts("http://SomeServer.com?jsonp=HandleRequest");
}
/ / the json callback
function HandleRequest(objJSON)
{
postMessage("Data returned from the server... FirstName: "
+ objJSON.FirstName + " LastName: " + objJSON.LastName);
}
// Trigger the server request for the JSONP data
MakeServerRequest();Copy the code
Communication principle
Communication from one thread to another is actually a process of value copying, which is actually json.stringify followed by json.parse. Binary data, such as files, BLObs, and arrayBuffers, can also be exchanged between the main thread and child threads, and can also be sent between threads. However, sending binary data as a copy can cause performance problems. For example, if the main thread sends a 50MB file to the child thread, by default the browser will generate a copy of the original file. To solve this problem, JavaScript allows the main thread to transfer binary data directly to the child thread, after which the main thread can no longer use the data. This is to prevent multiple threads from modifying data simultaneously. This method of transferring data is called Transferable Objects. However, many browsers now support Transferable Objects, a zero-copy transfer technology that can greatly improve performance by specifying that all data transferred is zero-copy
var abBuffer = new ArrayBuffer(32);
aDedicatedWorker.postMessage(abBuffer, [abBuffer]);Copy the code
You can also specify one to use zero copy
var objData = {
"employeeId": 103."name": "Sam Smith"."dateHired": new Date(2006.11.15),
"abBuffer": new ArrayBuffer(32)}; aDedicatedWorker.postMessage(objData, [objData.abBuffer]);Copy the code
Worker thread life cycle
Communication between worker threads must depend on the browser context and pass messages through their MessagePort object instances. The global scope of each worker thread has a list of ports for those threads, including MessagePort objects used by all threads. In the case of dedicated threads, the list also contains an implicit MessagePort object. The global scope object WorkerGlobalScope for each worker thread also has a list of worker threads, which is empty at initialization. They are populated when a worker thread is created or has a parent worker thread. Finally, the global scoped object WorkerGlobalScope for each worker thread also has the document model for that thread, which is empty at initialization. When a worker thread is created, the document object is populated. Whenever a document object is discarded, it is removed from the document object enumeration.
The performance test
Initialization test
// Some machines webwoker initialization time Macbook Pro:2 workers, 0.4 milliseconds on average
Macbook Pro: 4 workers, 0.6 milliseconds on average
Nexus 5: 2 workers, 6 milliseconds on average
Nexus 5: 4 workers, 15 milliseconds on average (border-line UI jank)
Copy the code
Transmission speed test
1. Common JSON /object
2, tranferable objects
Transferable visible objects
The transmission speed is much higher
Typical application scenarios are as follows
1) The simplest application of Web Worker is to do background calculation, which does not interrupt operations of foreground users. 2) Image processing by using data obtained from
limit
1. Read-only access to Location and Navigator that cannot access DOM and BOM objects, and navigator encapsulates as WorkerNavigator object, changing some properties. The local file system cannot be read. 2. The child thread communicates with the parent thread through value copy. The modification of the child thread to the communication content does not affect the main thread. 3, Not really multithreading, multithreading because of the browser function 4, compatibility 5 because threads import external JS through importScripts and execute directly, 6. Limit the number of webworker threads that can be created by most browsers. Although you can expand it manually, if you do not set it, it is basically within 20 threads, each thread is about 5M. You need to manually shut down some unused threads in order to create new threads (related solutions)
Js multithreaded library
1, tagg2
[1] www.html5rocks.com/zh… [2] www.alloyteam.com/2015… [3] typedarray.org/concur… [4] www.andygup.net/advanc… [5] developer.mozilla.org… [6] coolaj86.github.io/htm… [7] www.xyhtml5.com/webwor…