Introduction to JavaScript multithreading in HTML5 Web Worker

Source: Internet
Author: User
Tags http request setinterval

JavaScript single thread

The JavaScript language runs in a browser in a single thread. Speaking of a single thread, you have to start with the operating system process. Both processes and threads are operating systems. A process is an execution instance of an application. Each process is composed of a private virtual address space, code, data, and other system resources; A process can apply to create and use system resources (such as independent memory areas) during running, and these resources will be destroyed as the process ends. A thread is an independent execution unit in a process, and process resources can be shared among different threads. Therefore, in the case of multithreading, pay special attention to access control for critical resources. After the system creates a process, it starts the main thread of the execution process. The life cycle of the process is the same as that of the main thread. The exit of the main thread means that the process is terminated and destroyed. The main thread is created by the system process. You can also create other threads on your own. This series of threads will run concurrently in the same process.

Parallel processing of applications can be implemented in the case of multi-thread operations, which improves the performance and throughput of the entire application and extracts the CPU utilization of the local machine at a greater granularity, in particular, many modern languages support multi-core parallel processing technology. Then JavaScript is still executed in a single thread. Why?

This is because of the mission of the JavaScript script language: JavaScript is used to process user interaction on pages, and operate the DOM tree and CSS style tree to present a dynamic and rich interactive experience and interactive processing of server logic. If JavaScript is a multi-threaded method to operate these ui dom, there may be conflicts in UI operations. Under multi-threaded interaction, DOM nodes in the UI may become a critical resource, assume that two threads operate on a DOM simultaneously, and thread 1 requires the browser to delete the DOM node, but Thread 2 wants to modify some style of the node. In this case, the browser cannot decide which strategy to adopt. Of course, we can introduce "exclusive locks" or "optimistic locks" to the browser to solve these conflicts. But to avoid introducing greater complexity, JavaScript has chosen single-thread execution since its birth.

Because it is executed in a single thread, for JavaScript tasks, only one specific task can be executed at a time, and it will block other tasks. Will JavaScript execution be slow? Especially when a long task is executed, other tasks cannot be executed. However, in software development, especially in application software development, access to I/O devices is time-consuming. When these time-consuming tasks are executed, there is no need to wait for them to complete. Before the I/O task is completed, JavaScript can continue to execute other tasks, you can continue to process the task after the I/O task is completed. JavaScript was aware of this point at the beginning of its design. Therefore, in JavaScript, these time-consuming I/O operations are encapsulated as asynchronous methods. After these tasks are completed, subsequent processing operations are encapsulated as JavaScript tasks into the execution task queue, wait for the JavaScript thread to be executed when it is idle. Therefore, another topic, "browser event loop", will be discussed in detail later.

In JavaScript, unlike most other languages, time-consuming I/O operations in JavaScript are processed as asynchronous operations and callback registration mechanisms. Asynchronous and callback seem to be the same as JavaScript. As Ryan Dahl, founder of Nodejs, said, the non-blocking asynchronous I/O event-driven model of JavaScript language, as well as the multi-time optimization of JavaScript under Chrome, with functional and other advanced language features, therefore, Nodejs selects JavaScript. Since Nodejs finally chose JavaScript, it has greatly promoted the rapid expansion of JavaScript in the non-browser field.

The following text is from the official Node. Js website:


Of course, for non-I/O operations that are time-consuming, as mentioned in the previous article "Promise's past, present, present, and use tips", a new solution is also proposed in HTML5, which is Web Worker. Web Worker is to use the Worker class to open up an additional thread in the current main JavaScript execution thread to load and run specific JavaScript files, the new thread and the JavaScript main thread do not affect each other and block execution. In addition, the Web Worker provides the interface for data exchange between the new thread and the JavaScript main thread: postMessage and onMessage events. However, DOM cannot be operated in HTML5 Web Worker. Any task that requires DOM operations must be delegated to the JavaScript main thread for execution, therefore, although HTML5 WebWorker is introduced, it still does not change the nature of JavaScript single-thread. HTML5 Web Worker is similar to BackgroundWorker in the C # WinForm design. For applications operating on such GUI, operations on the UI interface must be delegated to the main UI thread for execution. This avoids the security of UI operations and the complexity of unnecessary multi-threaded access control.

Browser event loop

As mentioned above, many JavaScript tasks are asynchronous in order not to block UI rendering, these include keyboard, mouse I/O input and output events, window size resize events, timer (setTimeout, setInterval) events, Ajax request network I/O callbacks, and so on. When these asynchronous tasks occur, they will be placed in the event task queue of the browser. There is a message Loop pool in the browser, also called Event Loop. The JavaScript engine processes these Event tasks in a single thread after running. For example, if a user clicks a button event on a webpage, the event events are placed in the event loop pool, the execution thread will be executed one by one according to the first-in-first-out principle of the queue only when the execution thread is idle during JavaScript running. The same applies to timer tasks such as setTimeout. Only when the timer Time reaches will they be placed in the browser's event queue for execution; because the main JavaScript thread may not be idle at this time, it will not be executed immediately by the JavaScript engine, because the execution time of the timer tasks such as setTimeout in the JavaScript language design is not accurate. In front-end development, it is often found that setTimeout (func, 0) is very useful because it is not executed immediately, but put the currently executed callback function into the browser's event queue, wait until other tasks are completed, and then execute it; so setTimeout (func, 0) can change the execution sequence of the current code, this gives the browser the opportunity to complete the UI rendering and other tasks before executing this callback function. Of course, there is a 16 ms gap in older browsers. HTML5 is defined as 4 ms, and for the requestAnimationFrame in animation operations, please refer to the MDN documents https://developer.mozilla.org/en-us/docs/web/api/window/requestani.

The following figure shows the browser event loop:


Although JavaScript is executed in a single thread, browsers do not execute it in a single thread. They have JavaScript execution threads, UI node rendering threads, images, and other resource loading threads, and Ajax request threads. In Chrome design, to prevent the entire browser from being affected by the collapse of a Tab window, each of its tabs is designed as a process. There are many processes in Chrome design, and the use of inter-process communication to complete the synchronization between them, so this is one of Chrome's quick magic weapon. Special threads are also required to execute Ajax requests. When an Ajax request needs to be sent, the browser opens up a new thread to execute HTTP requests, it does not block the execution of JavaScript threads, and the HTTP request status change event will be put into the browser's event queue as a callback for execution.


HTML5 Web Worker with JavaScript multithreading

If you try to compute computation-intensive operations like fibonacci in JavaScript, the whole page experience will be blocked. The emergence of HTML5 Web Worker allows us to avoid blocking the current JavaScript thread, in the current JavaScript execution thread, you can use the Worker class to open up an additional thread to load and run specific JavaScript files, the new thread and the JavaScript main thread do not affect each other and block execution. In addition, the Web Worker provides the interface for data exchange between the new thread and the JavaScript main thread: postMessage and onmessage events. It is similar to the BackgroundWorker in C # WinForm.


Implement computation with fibonacci using Web Worker

Using HTML5 Web Worker to implement fibonacci can be shown as follows (plnkr online demo ):

Fibonacci. js Worker JavaScript file:

(Function (){
Var maid = function (n ){
Return n <2? 1: (maid (n-1) + maid (n-2 ));
};

Onmessage = function (event ){
PostMessage ({
Input: event. data,
Result: Maid (event. data)
});
};

})();

In fibonacci. js, the onmessage method is used to listen to the computation requests sent by the main thread, and postMessage is used to return the computation results to the request thread.

Script. js main thread JavaScript file:

$ (Function (){
Var $ input = $ ('# input '),
$ Btn = $ ('# btn '),
$ Result = $ ('# result '),
Worker = new Worker ('pythonacci. Js '),
TimeKey = function (val ){
Return 'pythonacci ('+ val + ')';
};

Worker. onmessage = function (event ){
Console. timeEnd (timeKey (event. data. input ));
$ Result. text (event. data. result );
};

$ Btn. on ('click', function (){
Var val = parseInt ($ input. val (), 10 );
If (val ){
Console. time (timeKey (val ));
$ Result. text ('? ')
Worker. postMessage (val );
    }
});
});

In this JavaScript file, use new Worker ('pythonacci. js') to create a Web Worker object, send request calculation requests using the postMessage method on the Worker object, and accept the results returned by the Worker thread using the onmessage method of the Worker object, and displayed on the UI. At the same time, we also used the latest time API of the console to calculate the time spent.

The result is as follows:

The time information printed on the console is:

Maid (10): 1.022 ms
Fibonacci (20): 1.384 ms
Fibonacci (30): 22.065 ms
Maid (40): 1744.352 ms
Fibonacci (50): 202140.027 ms

From the time output, we can see that the start time of the computation of fibonacci with n 40 is rapidly extended, and the return result time in the UI is also gradually extended; however, in Web Worker background computing, it does not block other interactions on our UI.


Web Worker summary

Web Worker is particularly useful in such time-consuming computing-intensive operations. In Web Worker, we can implement:

A js can be loaded for a large amount of complex computing without suspending the main process and communicating through postMessage and onmessage;
You can use importScripts (url) in worker to load another script file;
You can use setTimeout (), clearTimeout (), setInterval (), clearInterval ();
You can use XMLHttpRequest to send requests and access some attributes of navigator.

But it also has some restrictions from browser security sandbox:

Cross-Origin JavaScript files cannot be loaded;
As mentioned in the beginning of the file, considering the security of JavaScript DOM operations, DOM information in the interface cannot be accessed in Web Worker, DOM access operations must be delegated to the JavaScript main thread for operation; the emergence of HTML5 Web Worker does not change the fact that JavaScript is executed in a single thread;
There is also the compatibility of Web Worker browsers. Its browser compatibility diagram is as follows:



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.