vue3中使用Web Worker多线程
文章目录
- 问题描述
- Web Worker的作用
- 在vue3中使用
- ❀安装worker-loader
- ❀配置webpack
- ❀使用
- ts项目注意事项
- 获取项目Demo
- ❀CSDN:
- ❀Gitee:
问题描述
最近在做vue3的项目中,遇到了计算量庞大导致页面响应缓慢的问题,正好每个计算任务的结果不需要汇总,所以想到了以多线程的形式去执行每个计算任务。但是通过一轮google、baidu都没有找到vue3的案例,还好在外网的一篇案例中嗅到了一丝可能。
Web Worker的作用
大佬可以跳过, 对于Web Worker多线程可能有很多小伙伴还不知道是干嘛的,所以我先举一个列子让大家知道它大概是用来做什么的。
提示:用到的console如果看不懂的,可以到这篇文章学习:传送门
①洗完澡后再洗衣服: 在没有洗衣机(Worker)前,通常都是先洗完澡后再手洗衣服(这里我除外,我都是踩着衣服一起洗澡的),这样我们每天都要花费不少时间在洗澡和洗衣服上,花费时长为:洗澡所用时长+洗衣服所用时长
。相当于下面这段代码:
console.time('一共花了多少时长')
console.time('洗澡所用时长')
let length_1 = 300000000;
let sum1 = 0
for (let i = 0; i <= length_1; i++) {sum1 += i
}
console.log('%c循环1执行完:' + sum1, 'color:green')
console.timeEnd('洗澡所用时长')
console.time('洗衣服所用时长')
let length_2 = 200000000;
let sum2 = 0
for (let i = 0; i <= length_2; i++) {sum2 += i
}
console.log('%c循环2执行完:' + sum2, 'color:green')
console.timeEnd('洗衣服所用时长')
console.timeEnd('一共花了多少时长')
// 循环1执行完:45000000067108860
// 洗澡所用时长: 2712.139892578125 ms
// 循环2执行完:20000000067108864
// 洗衣服所用时长: 1751.049072265625 ms
// 一共花了多少时长: 4463.2490234375 ms
GIF输出效果:(从结果可以看到大概第2.7秒循环1执行完了,接着大概到了第4.5秒后循环2才执行完,所以从中可以看出循环1阻塞了循环2,所以此时花费时长为:循环1+循环2)
②把衣服放到洗衣机后洗澡: 当我们拥有洗衣机(Worker)后,就可以把衣服放到洗衣机后愉快的洗澡了,此时为异步操作,那么这时花费的总时长取决于谁更后洗完了,花费时长为:Math.max(洗澡所用时长,洗衣服所用时长)
。相当于下面的代码:
本地工作目录:
文件夹|-index.html|-worker.js
index.html:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Web Worker</title>
</head><body></body>
<script>console.time('洗衣机洗完衣服了,所用时长')var worker = new Worker("./worker.js"); // 开启副线程let length_1 = 300000000;let sum1 = 0worker.postMessage(length_1); // 发送消息给副线程worker.onmessage = e => { // 监听副线程返回的消息sum1 = e.dataconsole.log('%c循环1执行完了:' + e.data, 'color:green')console.timeEnd('洗衣机洗完衣服了,所用时长')worker.terminate() // 关闭线程}console.time('洗完澡了,所用时长')let length_2 = 200000000;let sum2 = 0for (let i = 0; i <= length_2; i++) {sum2 += i}console.log('%c循环2执行完了:' + sum2, 'color:green')console.timeEnd('洗完澡了,所用时长')
</script></html>
worker.js:
self.onmessage = function (e) { //监听主线程发过来的消息let length_1 = e.datalet sum = 0for (let i = 0; i <= length_1; i++) {sum += i}self.postMessage(sum); // 将信息发送到主线程上
}
GIF输出效果:(从结果可以看到大概第1.9秒循环2执行完了,紧接着接着大概第2.4秒后循环1也执行完了,当我们把循环1放到线程上执行时并没有阻塞后续的循环2,因为循环2循环时长短所以先打印出来了,因此此时花费总时长为:循环1)
虽然折腾这么久后只省了几秒钟,但是当项目计算量越来越大,多线程的优势就会变得特变明显了。
在vue3中使用
在vue项目中,如果直接使用Web Worker,会遇到worker文件路径与打包解析的问题,在做vue2.x项目时可以使用vue-worker插件去优雅的使用多线程,但我当我尝试在vue3中使用时,它依赖的simple-web-worker库会报Object.defineProperty called on non-object
的错误,应该是vue3把Vue全局对象给模块化了导致它拿不到对象,所以我放弃它了。经过一番查找,我发现还有另外一个方案,就是worker-loader插件,因为它是一个解析器所以我初步判断是可以在vue3中使用的,但是看过很多相关的博文,都没有能够在vue3中正常使用它(╯°Д°)╯︵┻━┻,最后终于在这篇外网博文中找到了可用代码,成功在vue3中跑起来了(T ^ T)
❀安装worker-loader
好了说了这么多,开始进入正题,我们先运行npm安装worker-loader
npm install worker-loader
安装成功后在package.json
文件的dependencies中可以看到
❀配置webpack
在vue.config.js文件
的defineConfig里加上配置参数
chainWebpack: config => {config.module.rule('worker-loader').test(/\.worker\.js$/).use({loader: 'worker-loader',options: {inline: true}}).loader('worker-loader').end()}
详细截图:
❀使用
先在src目录
下新建workers文件夹
,接着在里面新建worker.js
,在js文件里添加下面的测试代码:
addEventListener('message', e => {const { data } = econsole.log(data)setTimeout(() => {return postMessage('线程完成')}, 1000)
})
export default {}
详细截图:
之后就可以新建一个vue文件,加入下面代码进行测试:
引入js文件时需要使用
worker-loader!@
,并且路径是从src目录下开始数层级的,并非你执行的vue文件开始,这就是我一直不能正常跑起来的原因。
<template><div><h1>vue3-Worker</h1><button @click="openWorker">开启线程</button><p>F12打开浏览器控制台查看效果</p></div>
</template><script setup>
import Worker from 'worker-loader!@/workers/worker'
const openWorker = () => {const worker = new Worker()worker.postMessage('开启线程')worker.onmessage = e => {console.log(e.data)setTimeout(() => {worker.postMessage('线程关闭')worker.terminate()}, 1000)}
}
</script>
为了方便,我就直接用官方模板的HelloWorld.vue进行测试了:
GIF运行效果:(在控制台Console中可以看到线程的打印状态,源代码Sources的线程Threads中可以看到所有已开启的线程,手速快的按shift+esc也能看到)
ts项目注意事项
当你把代码写成typeScript时(因为线程跑完后我返回了字符串,所以event里的data需要声明为string),你会发现引入的ts文件路径会报波浪线:
这时我们需要在shims-vue.d.ts文件
中声明一下文件路径,直接为所有.ts文件声明也行:
获取项目Demo
有积分的交一下公粮,没有的话到Gitee下载就好
❀CSDN:
vue3-web-worker(js原味):传送门
vue3-ts-web-worker(ts风味):传送门
❀Gitee:
vue3-web-worker(js原味):传送门
vue3-ts-web-worker(ts风味):传送门
vue3中使用Web Worker多线程相关推荐
- 最小公倍数HTML,HTML5 Web Worker多线程编程实例 -- 计算最小公倍数和最大共约数
注释详细,不多解释!请看代码!!! 简单交互页面 index.html Web worker 最小公倍数和最大共约数 body { font-family: "微软雅黑"; fon ...
- 如何查找历史线程阻塞原因_学习 Web Worker(js中的“多线程”)
昨天部门例会,讨论开发的系统遇到的问题,遇到一个医保上传比较耗时的问题,解决方案提到了Web Worker,学习一波. 首先简单介绍一下什么是web worker.我们都知道在浏览器中javascri ...
- 关于Web Worker你必须知道的7件事
原文:http://www.developer.com/lang/jscript/7-things-you-need-to-know-about-web-workers.html 译者: Rock(r ...
- 浅析Web Worker及实践
本文讲述内容如下所示: Web Worker概述 API Web Worker在实际项目中应用 总结 一.Web Worker概述 1.Web Worker产生背景 众所周知JavaScript是单线 ...
- html5之web worker
Web Worker 在本文中 与 Web Worker 进行双向通信 WindowTimers 在 IE10 Platform Preview 4 中对 Web Worker 的更新 API 参考 ...
- web Worker简介、web Worker报错分析、作用
web Worker: web Worker是运行在后台的javascript,不会影响性能,常用于高耗费CPU的任务,必须部署到线上才可以正常使用,这里有三个方法比较重要,需要注意: postMes ...
- Dedicated Web Worker 和 Shared Web Worker
当在 HTML 页面中执行脚本(JS)时,页面的状态是不可响应的,直到脚本已完成. 通过使用Web Worker, 我们可以在浏览器后台运行Javascript, 而不占用浏览器自身线程.Web Wo ...
- 主进程中发生了一个javascript错误_知道html5 Web Worker标准吗?能实现JavaScript的多线程?
js为什么是单线程? 主要是因为最开始javascript是单纯的服务于浏览器的一种脚步语言(那时候没有nodejs).浏览器是为了渲染网页,通过dom与用户交互,如果一个线程需要给dom执行clic ...
- 深入理解javascript异步编程障眼法h5 web worker实现多线程
0.从一道题说起 var t = true; setTimeout(function(){ t = false; }, 1000); while(t){ } alert('end'); 1 2 3 4 ...
- Web Worker javascript多线程编程(一)
什么是Web Worker? web worker 是运行在后台的 JavaScript,不占用浏览器自身线程,独立于其他脚本,可以提高应用的总体性能,并且提升用户体验. 一般来说Javascript ...
最新文章
- 他曾创造多门编程语言,还被比尔·盖茨以300万美元挖角
- Resnet对应于ImageNet的结构框架
- 使用sqlmap 绕过防火墙进行注入测试
- 【深度学习入门到精通系列】图片OCR讲解
- 对我国域名系统安全问题的思考
- 从零写一个编译器(五):语法分析之自动机的缺陷和改进
- STM32打印log--使用J-Link RTT Viewer
- 数据结构与算法---常用三大排序算法
- 燕山大学高数AⅠ复习资料
- 选用计算机教材的理由原因,教材选用及管理规定
- 【Go】Go 语言运算符及其优先级
- 安装debian8操作系统
- 易语言dd驱动模拟按键模块_DD虚拟键盘虚拟鼠标
- Java常用设计模式(三)
- 处理器的排名_waste waltz家用垃圾处理器排名图片
- python字典操作 遍历_Python字典遍历操作实例小结
- 经度、纬度、高度转换成大地坐标系XYZ的程序
- 排序算法详解(Java实现 + 动画演示)
- CAD制图中,如何隐藏布局视口线框?
- 一款基于星座的app(项目已开源)
热门文章
- 在vue里引入使用Ag-grid表格插件
- 为什么不要用苹果的@icloud.com邮箱申请你的APP ID
- Vue前端编译问题集
- OSChina 周五乱弹 —— 为什么程序媛那么少?
- c语言中.def文件,VC++中的.DEF文件详解
- springboot基于java的校园二手书籍交易平台毕业设计源码131558
- 蓝湖访问显示“加载遇到问题”
- SCVMM 2012 R2---安装Hyper-V Server 2012 R2主机服务器
- 牛皮凉席不好的原因!
- 手机怎么设置腾达路由器后显示远端服务器,教你如何用手机快速设置腾达路由器...