Web Worker: A pseudo-antidote to JS multithreading?

Foreword

In the field of front-end development, the single-threaded limitation of JavaScript has always been a challenge that is difficult to ignore. When it comes to solving the single-threaded limitations of JavaScript, the Web Worker introduced by HTML5 is widely regarded as an antidote. At the same time, a large number of articles in the industry focus on discussing the magical power of web workers. However, this article will take a different approach and explore with you the mysterious other side of Web Workers.

JS single-thread limitation and multi-thread capability requirements

One of the characteristics of js is single thread. For single threads, the most classic summary is “Only one task can be executed at the same time.”

When JavaScript was originally designed, its single-threaded model was determined by its primary purpose and original intention. As a browser-side scripting language, JavaScript’s initial main task is to handle user interaction. Imagine that if JavaScript is designed to be multi-threaded, then multi-thread synchronous operation of the DOM during user interaction will inevitably lead to complex issues such as race allocation in order to ensure accuracy. In addition, for the client, it may also cause various complex problems such as performance and resource consumption. At this time, multi-threading appears to be too bloated in this context.

With the continuous evolution of Web technology, JavaScript’s single-threaded model can no longer meet the increasingly complex business needs and performance requirements. In order to solve these problems, JavaScript has introduced some mechanisms such as ajax, setTimeout, requestAnimationFrame, etc., but it needs to be clear that these mechanisms are just through The illusion of multi-threading created by EventLoop does not change the single-threaded nature of JavaScript.

So far, user interactions in modern web applications have become more and more complex, and data processing requirements have increased. JavaScript applications require stronger computing power and faster responsiveness, and the single-threaded model is facing increasingly serious challenges. This leads to a key question: How to maintain the single-threaded nature of JavaScript while taking full advantage of multi-core processors to improve performance to meet user needs? In this context, Web Worker technology emerged as the times require.

Definition of web worker

Maybe you haven’t used Web Workers in your projects yet, but they have been around for a long time. As early as 2009, W3C proposed a Web Worker draft, which 2011 was officially called part of the HTML5 standard.

Image Description

W3C defines Web Worker as follows:

an API for running scripts in the background independently of any user interface scripts.

Compatibility

image.png

The most simple and clear example

//Main thread code
const worker = new Worker('worker.js');
worker.postMessage('Hello from the main thread!');
worker.onmessage = (event) => {
  console.log('Message from Web Worker:', event.data);
};

// worker.js
self.onmessage = (event) => {
  console.log('Message from main thread:', event.data);
  self.postMessage('Hello from the Web Worker!');
};
Other types of extensions

In addition to the dedicated worker type (Dedicated Web Worker), there are two special Web Workers: SharedWorer and ServiceWorker.

  • SharedWorker can access the same Worker instance in multiple browser tabs, allowing multiple tabs to share data, such as sharing webSocket connections. However, it looked great, but compatibility issues were once serious. In particular, Safari started supporting it in iOS 5 in 2012, then it didn’t support it in iOS 7~15, and then it supported it again in iOS 16. It was really confusing!
  • ServiceWorker can intercept and process network requests, implement offline caching, push notifications and other advanced network functions, which is also very interesting. Students who have done PWA know that SW is its core part.

sharedWorker compatibility:

image.png

Advantages of Web Worker

The Web Worker is independent of the main thread and can perform some time-consuming operations without blocking the main thread without affecting the performance of the main thread. It is especially useful when processing complex tasks and long-running operations. Its main advantages are as follows:

  • Independent operation: Web Worker runs in an independent thread and does not interfere with the main thread. This can prevent the main thread from stalling due to time-consuming operations, thereby improving the page’s response speed and user experience.
  • Isolation mechanism: Web Workers cannot directly access or operate DOM elements. This isolation mechanism can prevent potential page modifications and malicious attacks, ensuring the security and stability of web pages.
  • Multi-threaded asynchronous execution: Web Worker allows you to create multiple independent threads in the tab process. Each thread can execute on a different core, so parallel computing can be achieved.

Practical application scenarios of Web Worker

In actual projects, Web Worker is more suitable for handling the following scenarios:

  • Computationally intensive tasks: for example, data analysis, image processing, encryption algorithms, etc. These tasks usually take a long time and require high CPU performance. By delegating these tasks to Web Workers, you avoid blocking the main thread, thus keeping your application responsive.
  • Asynchronous operations: When you need to perform some asynchronous operations, such as getting data from a server, you can use Web Worker to avoid main thread jams caused by waiting for the asynchronous operation to complete.
  • Artificial intelligence: Web Worker can be used to handle parallel computing during training or inference of machine learning models, thereby improving the training speed and responsiveness of the model.

Limitations of Web Worker

  • Compatibility issues: Although HTML5 has become popular, Web Worker is only supported in the latest major versions of most manufacturers’ browsers, and is not well supported in older versions. This causes developers to give up using Web Workers in actual projects.

  • Resource restrictions: unable to directly access DOM, same-origin policy, unable to read local files, etc.

  • Programming complexity: Using Web Workers requires handling communication between threads, which increases programming complexity. Using Web Workers for simple tasks may not be cost-effective.

  • Security issues: Because the Web Worker is multi-threaded running in the background, it is more hidden, which also brings new security issues: such as the injection of malicious scripts to use the Web Worker to perform large-scale multi-threaded attacks to amplify the attack effect, Maliciously creating a large number of web workers and letting them perform high-load tasks can cause browser crashes. ImportScripts without cross-domain restrictions may load untrusted scripts, leading to security vulnerabilities, etc.

Web Worker communication efficiency issues

In addition to the above limitations, the communication efficiency of Web Worker is also worth noting.

  • Unable to share memory: Unlike traditional multi-threaded programming, Web Workers cannot directly share memory. Data transfer between the main page and workers is completed through copy rather than sharing. Therefore, large amounts of memory and processing time may be consumed in scenarios such as large file transfers.

  • Data serialization problem: When data is exchanged between the main thread and the Web Worker, the data needs to be serialized and deserialized. Serialization will block the sender, while deserialization will block the receiver. So even small data needs to go through this process. This may accumulate and become a performance bottleneck under frequent communications.

  • postMessage: The postMessage method itself is not the main cause of low communication efficiency, but is caused by other factors such as the Worker thread needing to frequently send a large number of messages to the main thread, or the message size being large. This may cause the main thread to process messages less quickly than the Worker thread to send messages, causing communication congestion and performance issues.

Main thread Web Worker data transmission data transmission postMessage(data)onmessage(event) serialized data send serialized data deserialized data postMessage(replyData) serialized reply data send serialized reply data deserialized reply data main thread Web Worker

Problems caused by communication efficiency

Due to limitations in communication efficiency, Web Worker is not suitable for real-time tasks. Web Workers cannot guarantee real-time performance due to messaging overhead and possible network delays. Therefore, for some scenarios that require real-time response, such as online games and video conferencing, using Web Workers may not be the best choice.

Thinking: With the Web Worker API, has JavaScript really become a multi-threaded language?

As mentioned in the “Thread Safety” section of MDN’s web worker:

"The Worker interface spawns real OS-level threads".

From an underlying technology perspective, Web Worker does have multi-threading characteristics. However this is different from traditional multi-threaded programming languages such as Java or C++. For example, the main thread in JavaScript and the Web Worker use message passing to communicate instead of directly sharing memory. This means that data cannot be shared directly between Web Workers, while traditional multi-threaded languages can share memory directly, allowing for more direct and efficient inter-thread communication.

Although Web Worker has multi-threading characteristics from the underlying technology, the main application area of JavaScript today is still processing user interface and user interaction. The introduction of Web Worker is mainly to improve the responsiveness of front-end applications so that they can better Handle some computationally intensive tasks without completely transforming JavaScript into a multi-threaded programming language.

In summary, although the Web Worker API provides a certain degree of multi-threaded support for JavaScript, JavaScript is still a programming language that mainly relies on single-threaded execution. Web Worker does not change the single-threaded nature of JavaScript.

The future outlook of js multi-threading technology

In the future, js multi-threading should have better performance, better responsiveness and more parallel computing capabilities. With the continuous development of Web technology, the prospects of multi-threading are becoming more and more broad. like:

  • The continuous development of browser engines and hardware acceleration technology makes it more feasible to handle complex multi-threaded tasks in the browser;
  • Opportunities that may arise from the integration of new technologies such as WebAssembly;
  • As the ECMAScript standard continues to evolve, you can expect the introduction of more multi-threading-related functions and APIs to better support parallel computing.

Summary

To sum up, Web Worker, as a multi-threaded tool in front-end development, does have its unique advantages. However, we must understand that although it is widely regarded as a way to solve the single-threaded problem of JavaScript, it does not fundamentally change the single-threaded nature of JavaScript. When using Web Workers, we still need to face issues such as resource limitations, communication overhead, and security. Therefore, it can be said that Web Worker is a “pseudo antidote”. It helps alleviate JavaScript’s single-threaded limitations, but it’s not a silver bullet. In the future, we look forward to further development in the field of JavaScript multi-threading to achieve continued improvement in Web capabilities?!?!

Original link: https://juejin.cn/post/7274146202496565306