Webwork solves the problem that js will block pages if it takes too long to execute

As we all know, JS runs in a single-threaded environment, which means you can’t run multiple scripts at the same time. If a user clicks a button and starts a piece of JAVASCRIPT code for calculation, it will not be able to respond to the user’s other actions until the code is executed. However, if this code is run by WebwOK, the situation is different: the browser starts a separate worker thread in the background to run this code, so the page can still respond to other user actions while the JS code is running

Introduction of web worker

Web workers are part of the HTML5 standard, which defines a set of apis that allow a JS program to run in the main thread from another thread.

The Web Worker specification defines two types of worker threads

Dedicated worker: A dedicated worker that uses a page

Shared worker: Multiple pages can be shared

What does Web Worker bring to JS

Strong computing power

It can load a JS to perform a large number of complex calculations without suspending the main process, and communicate via postMessage and onMessage, which solves the problem of blocking UI rendering due to a large number of calculations

The characteristics of

  1. The same-origin restrictions

The script file assigned to the worker thread must be of the same origin as the script file of the main thread

  1. DOM limit

Unlike the main thread, the global object where the worker thread resides cannot read the DOM object of the page where the main thread resides, nor can it use the document, window, parent objects. However, worker threads have navigator objects and Location objects

  1. A correspondence

The worker thread and the main thread are not in the same context; they cannot communicate directly and must do so through messages

4. The script restricts the worker thread from executing the alert () and confirm () methods, but can make AJAX requests using the XMLHttpRequest object

  1. File limit

The work thread cannot read local files, nor can it open the current season’s file system. The loaded scripts must come from the network

Application scenarios

  1. Mathematical operations

The simplest use of Webworker is for background computing, which is perfect for CPU-intensive scenarios

  1. The image processing

By using the data obtained from it, the image can be divided into several different regions and pushed to different parallel workers for calculation. Pixel-level processing of the image is carried out, and then the processed image data is returned to the main page

  1. Big data processing

At present, the MVVM framework is becoming more and more popular, and the data-driven development mode is becoming more and more popular. In the future, the processing of big data may come to the foreground. At this time, it is also the best way to transfer the processing of big data to Web worker

How to use Webworker

Create a worker

A new worker can be created by simply calling the worker () constructor and passing in an obtuse URL to run in the worker thread.

var myWorker = new Worker('my-task.js');

// code in my-task.js

var i = 0;
function timedCount(){
    i = i+1;
    postMessage(i);
    setTimeout(timedCount, 1000);
}
timedCount();
Copy the code

In addition, create URL objects through url.creatobjecturl () to realize embedded Webworker

var myTask = ` var i = 0; function timedCount(){ if(i<=3){ i = i+1; postMessage(i); setTimeout(timedCount, 1000); } } timedCount(); `;

var blob = new Blob([myTask]);
var myWorker = new Worker(window.URL.createObjectURL(blob));
Copy the code

In this way, you can combine NEJ, Webpack module management, packaged

Note: Arguments passed into the worker constructor must follow the same origin policy. Worker threads are created in the same way that the main thread code does not block waiting for the worker thread to go to the shelf and execute the specified script file, but immediately continues to execute the following code

Worker Thread data communication mode

Communication between workers and their home pages is achieved through onMessage events and postMessage () methods.

The data transferred between the main page and the Worker is copied rather than shared. Passing objects to workRT requires serialization, followed by deserialization at the other end. Workers do not share the same instance, and the end result is that a copy of the data is generated at the end of each communication.

In other words, workers can only pass data between their home pages, not complex reference types: objects created through constructors, etc. Moreover, the data passed is also a copy of the data generated by the copy, and changes made to the data on one side will not affect the other.

var myTask = ` onmessage = function (e) { var data = e.data; data.push('hello'); console.log('worker:', data); // worker: [1, 2, 3, "hello"] postMessage(data); }; `;

var blob = new Blob([myTask]);
var myWorker = new Worker(window.URL.createObjectURL(blob));

myWorker.onmessage = function (e) {
    var data = e.data;
    console.log('page:', data); // page: [1, 2, 3, "hello"]
    console.log('arr:', arr); // arr: [1, 2, 3]
};

var arr = [1.2.3];
myWorker.postMessage(arr);
Copy the code

Data is passed through transferable objects

The performance of transferring data through transferable objects is higher, and data can be shuttled back and forth between the main page and the worker through transferable objects. Transferable objects are moved from one context to another without any copy operation. This means significant performance gains when delivering big data.

Unlike passing by reference, once an object is transferred, it ceases to exist in that version of its original context. Ownership of the object is transferred to the new context.

For example, when you transfer an ArrayBuffer object from the main application to the worker, the original ArrayBuffr is emptied and unusable. The content it contains is passed (complete and flawless) to the worker context.

var uInt8Array = new Uint8Array(1024*1024*32); // 32MB
for (var i = 0; i < uInt8Array .length; ++i) {
  uInt8Array[i] = i;
}

console.log(uInt8Array.length); // Length before transfer :33554432

var myTask = ` onmessage = function (e) { var data = e.data; console.log('worker:', data); }; `;

var blob = new Blob([myTask]);
var myWorker = new Worker(window.URL.createObjectURL(blob));
myWorker.postMessage(uInt8Array.buffer, [uInt8Array.buffer]);

console.log(uInt8Array.length); // Length after passing :0
Copy the code

importScripts()

The Worker thread can access a global function imprtScripts() to import the script, which takes zero or more URIs as arguments. The browser loads and runs each of the listed scripts, and the global objects in each script can be used by the worker. If the script cannot be loaded, NETWORK_ERROR is thrown and the following code cannot be executed. The previously executed code (including code executed asynchronously with window.setTimeout()) will still run. Function declarations after importScripts() are still retained because they are always run before other code. Note: Scripts are downloaded in a variable order, but are executed in the order of file names passed in importScripts(). This is done synchronously; ImportScripts () does not return until all scripts have been downloaded and run.

The worker context

The context of Worker execution is different from that of the main page execution. The top-level object is not Window, but something called WorkerGlobalScope, so window and the DOM API related to window cannot be accessed. But you can work with setTimeout, setInterval, and so on. Common attributes and methods under the scope of WorkerGlobalScope are as follows:

  1. self

We can use the Self attribute of the WorkerGlobalScope or reference the object itself

  1. location

The Location property returns the WorkerLocation object associated with the thread when it is created, which represents the absolute URL of the footstep resource used to initialize the worker thread. This URL resource location does not change even after the page is redirected multiple times.

  1. close

Close the current thread

  1. importScript

We can load library functions from the worker via the URL via the importScripts() method

  1. XMLHttpRequest

With this, Ajax requests can be made

  1. SetTimeout and setInterval and addEventListener/postMessage

Terminate: Calling terminate() on the home page immediately kills the worker thread without leaving any opportunity for it to complete its operations or clean up. In addition, the worker can also call its own close() method to close itself

    // home page call
    myWorker.terminate();

    // the Worker thread calls
    self.close();
Copy the code

Handling errors

When the worker encounters a runtime error, its onError event handler is called. It receives an event named Error that implements the errorEvent interface.

The event does not bubble and can be cancelled

To prevent triggering the default action, the worker can call the preventDefault() method of the error event

The error event has three attributes to use: filename- the filename of the script in which the error occurred; Lineno – Wrong line number; And message- a readable error message

var myTask = ` onmessage = function (e) { var data = e.data; console.log('worker:', data); }; // Use the undeclared variable arr.push('error'); `;

var blob = new Blob([myTask]);
var myWorker = new Worker(window.URL.createObjectURL(blob));
myWorker.onerror = function onError(e) {
    // ERROR: Line 8 in blob:http://www.cnblogs.com/490a7c32-7386-4d6e-a82b-1ca0b1bf2469: Uncaught ReferenceError: arr is not defined
    console.log(['ERROR: Line ', e.lineno, ' in ', e.filename, ':', e.message].join(' '));
}

Copy the code

Service Worker

What is the

A middleman role between the server and the browser. If a service worker is registered in the website, it can intercept all the requests of the current website and make judgment (corresponding judgment program needs to be written). If it needs to send requests to the server, it can transfer them to the server. If you can use the cache directly, you just return it to the cache and don’t transfer it to the server. Thus greatly enhancing the browsing experience.

Detailed description

  • Based on web workers (a separate thread from the main thread of JavaScript, where resource-intensive operations are performed without blocking the main thread)
  • Essentially acts as a proxy server between the server and the browser (intercepts site-wide requests and acts accordingly -> actions specified by the developer
  • Add the ability of offline cache on the basis of Web worker
  • Create an effective offline experience (cache infrequently updated content in the browser to improve the experience)
  • Event-driven and has a life cycle
  • Catche and indexDB are accessible
  • Support to push
  • It also allows developers to manage the content and version of the cache themselves

Matters needing attention

  1. Service worker running in the worker context —– cannot access the DOM
  2. Fully asynchronous, synchronous apis such as XHR and localStorage are no longer available in Service Work
  3. For security reasons, the service worker can only be hosted by HTTPS
  4. In the User privacy mode of Firefox, service Work is unavailable
  5. Its life cycle is page-independent (it can exit if the associated page is not closed, and it can start without the associated page)