Article directory
- 1 Introduction
- 2. Introduction to Web Worker
- 3. Instructions for use and compatibility
-
- 3.1. Instructions for use
- 3.2. Compatibility
- 4. Use Web Worker
-
- 4.1. Create Web Worker
- 4.2. Communicate with the main thread
- 4.3. Terminate Web Worker
- 4.4. Monitor error messages
- 5. Use Shared Worker
-
- 4.5. Debugging Shared Worker
- 6. Some pitfalls in use
-
- 6.1. Other files introduced in Web Woeker
- 6.2. Use in WebPack or Vite
-
- 6.2.1, used in webpack
- 5.2.2, used in vite
- 5.3. Problems with the introduction of sharedWorker
- 7. Postscript
1. Foreword
The interface stuck in a project I was working on recently. After some investigation, I found out that it was because some data had been formatted and generated. Originally there were only 1,000 pieces of data, but after processing, it became N million pieces of data (business demand), causing the page to render very slowly or even crash. So I thought about optimizing it. It is not loaded during initialization. When needed, the Web Worker is used to process the data to avoid the main thread getting stuck.
2. Introduction to Web Worker
Before introducing it, let’s talk about why Web Worker was born.
Because the JavaScript language uses a single-threaded model, that is to say, all tasks can only be completed on one thread, and only one thing can be done at a time. The previous tasks have not been completed, and the subsequent tasks can only wait. With the enhancement of computer computing power, especially the emergence of multi-core CPUs, single-threading has brought great inconvenience and cannot fully utilize the computer’s computing power.
The role of Web Worker is to create a multi-threaded environment for JavaScript. It is part of the HTML5 standard and gives developers the ability to operate multiple threads using JavaScript. Allow the main thread to create Worker threads and assign some tasks to the Worker threads to run. While the main thread is running, the Worker thread is running in the background, and the two do not interfere with each other. Wait until the Worker thread completes the calculation task, and then returns the result to the main thread. The advantage of this is that some computing-intensive or high-latency tasks are burdened by the Worker thread, and the main thread (usually responsible for UI interaction) will be smooth and will not be blocked or slowed down.
3. Instructions for use and compatibility
Before using Worker, you need to understand some rules and browser compatibility to avoid some problems.
3.1. Instructions for use
-
Resource consumption: Once the Worker thread is successfully created, it will always run and will not be interrupted by activities on the main thread (such as the user clicking a button or submitting a form). This is conducive to responding to the main thread’s communication at any time. However, it also causes the Worker to consume more resources, so it is recommended to close it after use.
-
Same-origin restriction: The script file assigned to the Worker thread must have the same origin as the script file of the main thread.
-
DOM limitation: The global object where the Worker thread is located is self, which is different from the main thread. It cannot read the window, DOM, document, parent and other global objects of the webpage where the main thread is located, but it can read the navigator and location objects of the main thread. .
-
Script limitation: XMLHttpRequest and Axios can be used in Web Workers to send requests.
-
Communication: The Worker thread and the main thread are not in the same context, they cannot communicate directly and must be completed through messages.
-
File restrictions: Local files cannot be read in the Worker thread, that is, the local file system (file://) cannot be opened. The script it loads must come from the network.
3.2, Compatibility
Browser | Compatibility | Minimum compatible version |
---|---|---|
Chrome | Fully compatible | 4.0 (2008) |
Firefox | Fully compatible | 3.5 (2009) |
Safari | Fully compatible with | 3.1 (2007) |
Edge | Fully compatible | 79 (2020) |
IE | Partially compatible | 10 (2012) |
Opera | Fully compatible | 10.5 (2010) |
4. Use Web Worker
Directly use JavaScript’s native Worker() constructor, whose parameters are as follows:
Parameters | Description |
---|---|
path | The address of a valid js script must comply with the same origin policy |
options.type | Optional. Used to specify the worker type. The value can be classic or module. The default is classic |
options.credentials | optional. Specify worker credentials. The value can be omit, same-origin, or include. If not specified, or type is classic, the default omit will be used (no credentials required) |
options.name | Optional. In the case of DedicatedWorkerGlobalScope, a DOMString value representing the scope of the worker, primarily for debugging purposes. |
4.1. Create Web Worker
Main thread:
const myWorker = new Worker('/worker.js') //Receive message myWorker.addEventListener('message', (e) => {<!-- --> console.log(e.data) }) //Send message to worker thread myWorker.postMessage('Greeting from Main.js')
4.2. Communication with the main thread
worker thread:
//Receive message self.addEventListener('message', (e) => {<!-- --> console.log(e.data) }) // After a calculation, send the message const calculateDataFn = () => {<!-- --> self.postMessage('ok') }
4.3. Terminate Web Worker
You can operate in both threads, you can choose freely.
- Operate in the main thread:
//Create worker const myWorker = new Worker('/worker.js') // Close the worker myWorker.terminate()
- Operate in the worker thread:
self.close()
4.4. Monitoring error messages
Web Worker provides two event listening error callbacks, error and messageerror.
Event | Description |
---|---|
error | Triggered when an error occurs within the worker |
messageerror | Triggered when the message event receives parameters that cannot be deserialized |
- Operate in the main thread:
//Create worker const myWorker = new Worker('/worker.js') myWorker.addEventListener('error', (err) => {<!-- --> console.log(err.message) }) myWorker.addEventListener('messageerror', (err) => {<!-- --> console.log(err.message) })
- In the worker thread:
self.addEventListener('error', (err) => {<!-- --> console.log(err.message) }) self.addEventListener('messageerror', (err) => {<!-- --> console.log(err.message) })
5. Use Shared Worker
SharedWorker allows multiple pages to share the same background thread, allowing for more efficient resource utilization and collaborative computing. The following is an example, page1
and page2
share a background thread:
- sharedWorker.js
/** * @description The collection of all connections to this worker */ const portsList = [] /** * @description Connection success callback */ self.onconnect = (event) => {<!-- --> //The port currently triggering the connection const port = event.ports[0] // add in portsList.push(port) //Callback when message is received port.onmessage = (event) => {<!-- --> // Get the delivered message const {<!-- --> message, value } = event.data \t\t// calculate let result = 0 switch (message) {<!-- --> case 'add': result = value * 2 break case 'multiply': result = value * value break default: result = value } //Send message to all connected targets portsList.forEach((port) => port.postMessage(`${<!-- -->message}The result is: ${<!-- -->result}`)) } }
- sharedWorkerHook.js
const sharedWorker = new SharedWorker(new URL('../../utils/webworker.js', import.meta.url), 'test') export default sharedWorker
- page1
<template> <div @click="sendMessage">Click 1</div> </template> <script> import sharedWorkerHook from './sharedWorkerHook' export default {<!-- --> name: '', data() {<!-- --> return {<!-- -->} }, computed: {<!-- -->}, created() {<!-- -->}, mounted() {<!-- --> sharedWorkerHook.port.start() //Receive the results returned by SharedWorker sharedWorkerHook.port.onmessage = event => {<!-- --> console.log(event.data) } }, methods: {<!-- --> sendMessage() {<!-- --> sharedWorkerHook.port.postMessage({<!-- --> message: 'add', value: 1 }) } } } </script>
- page2
<template> <div @click="sendMessage">Click 2</div> </template> <script> import sharedWorkerHook from './sharedWorkerHook' export default {<!-- --> name: '', data() {<!-- --> return {<!-- -->} }, computed: {<!-- -->}, created() {<!-- -->}, mounted() {<!-- --> sharedWorkerHook.port.start() //Receive the results returned by SharedWorker sharedWorkerHook.port.onmessage = event => {<!-- --> console.log(event.data) } }, methods: {<!-- --> sendMessage() {<!-- --> sharedWorkerHook.port.postMessage({<!-- --> message: 'multiply', value: 1 }) } } } </script>
4.5, Debugging Shared Worker
When debugging in sharedWorker, use console to print information. It will not appear in the console of the main thread. You need to enter chrome://inspect/ in the Chrome browser address bar and enter the debugging panel to see it. The steps are as follows:
- Enter chrome://inspect in the Chrome browser address bar and press Enter to enter
- In the left menu bar, click sharedWorker
- In the menu bar on the right, click inspect to open the debugging panel.
6. Some pitfalls in use
During use, although I checked some documents and blogs, the following problems still occurred. Please record them.
6.1, Other files introduced in Web Woeker
In some scenarios, the tasks that need to be processed by the worker process are very complex, and other files will be introduced. At this time, we can use the importScripts() method in the worker thread to load the js files we need.
importScripts('./utils.js')
If the ESModule mode is introduced, the type mode needs to be specified during initialization.
const worker = new Worker('/worker.js', {<!-- --> type: 'module' })
6.2. Use in WebPack or Vite
To use it in webpack and vite, the steps are as follows:
6.2.1, used in webpack
Step 1: Install the plug-in: worker-plugin
npm install worker-plugin -D
Step 2: Configure in configureWebpack.plugins of vue.config.js
const WorkerPlugin = require('worker-plugin') module.exports = {<!-- --> outputDir: 'dist', //The rest of the configuration... configureWebpack: {<!-- --> devServer: {<!-- --> open: false, host: 'localhost', //The rest of the configuration... }, plugins: [ //The rest of the configuration... new WorkerPlugin() ] } }
Step 3: Use
const webWorker = new Worker(new URL('../utils/worker.js', import.meta.url), {<!-- --> type: 'module' })
5.2.2, used in vite
Step 1: Install the plug-in: worker-plugin
npm install worker-plugin -D
Step 2: Configure in plugins of vite.config.js
import worker from 'worker-plugin' const viteConfig = defineConfig((mode: ConfigEnv) => {<!-- --> return {<!-- --> plugins: [vue(), worker()], server: {<!-- --> host: '0.0.0.0', port: 7001, open: true } } }) export default viteConfig
Step 3: Use
const webWorker = new Worker(new URL('../utils/worker.ts', import.meta.url), {<!-- --> type: 'module' })
5.3. Problems with the introduction of sharedWorker
In the process of using sharedWorker, I found that there is always only one instance in the sharedWorker process, but I did initialize the same sharedWorker js file on several pages. Finally, debugging found that the reason was that the name changed after being introduced through the plug-in. One is xxxx0.js and one is xxxx1.js, so every time I initialize, they are not considered to be the same instance, so the messages cannot be synchronized.
- Solution: Just like the example in [Use Shared Worker] (#5-Use Shared Worker), use a new file to create this sharedWorker, then export it, and then execute it after importing the required page.
like
7. Postscript
In this article, we learned the role and use of Web Worker, and how to use Web Worker in Vue. Finally, we also learned how to use Shared Worker.
In fact, there is a more powerful member of the webworker family, which is Service Worker. It can do many things, such as intercepting global fetch events, caching static resources/offline caching for first-screen loading, background synchronization, message push, etc. However, the space is limited, so I will explain it next time.
That’s it for this sharing. I am Peng Duoduo. If you find it helpful, please comment, follow, like, and forward. See you next time~
Previous articles
- PC-side online music website built by Vue2 Family Bucket + Element
- vue3 + element-plus configure cdn
- Vue3 tutorial to help you get started with Vue3 Family Bucket
- VueX4 tutorial to help you get started with Vue3 Family Bucket
- Vue-Router4 tutorial to help you get started with Vue3 Family Bucket
- Super detailed! Nine communication methods in Vue
- Super detailed! Vuex step-by-step tutorial
- Use nvm to manage node.js version and replace npm Taobao mirror source
- In vue, .env files are used to store global environment variables and configure vue startup and packaging commands.
- Super detailed! Vue-Router step-by-step tutorial
Personal homepage
- CSDN
- GitHub
- Simple book
- Blog Garden
- nuggets