文章目录

  • 问题描述
  • 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多线程相关推荐

  1. 最小公倍数HTML,HTML5 Web Worker多线程编程实例 -- 计算最小公倍数和最大共约数

    注释详细,不多解释!请看代码!!! 简单交互页面 index.html Web worker 最小公倍数和最大共约数 body { font-family: "微软雅黑"; fon ...

  2. 如何查找历史线程阻塞原因_学习 Web Worker(js中的“多线程”)

    昨天部门例会,讨论开发的系统遇到的问题,遇到一个医保上传比较耗时的问题,解决方案提到了Web Worker,学习一波. 首先简单介绍一下什么是web worker.我们都知道在浏览器中javascri ...

  3. 关于Web Worker你必须知道的7件事

    原文:http://www.developer.com/lang/jscript/7-things-you-need-to-know-about-web-workers.html 译者: Rock(r ...

  4. 浅析Web Worker及实践

    本文讲述内容如下所示: Web Worker概述 API Web Worker在实际项目中应用 总结 一.Web Worker概述 1.Web Worker产生背景 众所周知JavaScript是单线 ...

  5. html5之web worker

    Web Worker 在本文中 与 Web Worker 进行双向通信 WindowTimers 在 IE10 Platform Preview 4 中对 Web Worker 的更新 API 参考 ...

  6. web Worker简介、web Worker报错分析、作用

    web Worker: web Worker是运行在后台的javascript,不会影响性能,常用于高耗费CPU的任务,必须部署到线上才可以正常使用,这里有三个方法比较重要,需要注意: postMes ...

  7. Dedicated Web Worker 和 Shared Web Worker

    当在 HTML 页面中执行脚本(JS)时,页面的状态是不可响应的,直到脚本已完成. 通过使用Web Worker, 我们可以在浏览器后台运行Javascript, 而不占用浏览器自身线程.Web Wo ...

  8. 主进程中发生了一个javascript错误_知道html5 Web Worker标准吗?能实现JavaScript的多线程?

    js为什么是单线程? 主要是因为最开始javascript是单纯的服务于浏览器的一种脚步语言(那时候没有nodejs).浏览器是为了渲染网页,通过dom与用户交互,如果一个线程需要给dom执行clic ...

  9. 深入理解javascript异步编程障眼法h5 web worker实现多线程

    0.从一道题说起 var t = true; setTimeout(function(){ t = false; }, 1000); while(t){ } alert('end'); 1 2 3 4 ...

  10. Web Worker javascript多线程编程(一)

    什么是Web Worker? web worker 是运行在后台的 JavaScript,不占用浏览器自身线程,独立于其他脚本,可以提高应用的总体性能,并且提升用户体验. 一般来说Javascript ...

最新文章

  1. 他曾创造多门编程语言,还被比尔·盖茨以300万美元挖角
  2. Resnet对应于ImageNet的结构框架
  3. 使用sqlmap 绕过防火墙进行注入测试
  4. 【深度学习入门到精通系列】图片OCR讲解
  5. 对我国域名系统安全问题的思考
  6. 从零写一个编译器(五):语法分析之自动机的缺陷和改进
  7. STM32打印log--使用J-Link RTT Viewer
  8. 数据结构与算法---常用三大排序算法
  9. 燕山大学高数AⅠ复习资料
  10. 选用计算机教材的理由原因,教材选用及管理规定
  11. 【Go】Go 语言运算符及其优先级
  12. 安装debian8操作系统
  13. 易语言dd驱动模拟按键模块_DD虚拟键盘虚拟鼠标
  14. Java常用设计模式(三)
  15. 处理器的排名_waste waltz家用垃圾处理器排名图片
  16. python字典操作 遍历_Python字典遍历操作实例小结
  17. 经度、纬度、高度转换成大地坐标系XYZ的程序
  18. 排序算法详解(Java实现 + 动画演示)
  19. CAD制图中,如何隐藏布局视口线框?
  20. 一款基于星座的app(项目已开源)

热门文章

  1. 在vue里引入使用Ag-grid表格插件
  2. 为什么不要用苹果的@icloud.com邮箱申请你的APP ID
  3. Vue前端编译问题集
  4. OSChina 周五乱弹 —— 为什么程序媛那么少?
  5. c语言中.def文件,VC++中的.DEF文件详解
  6. springboot基于java的校园二手书籍交易平台毕业设计源码131558
  7. 蓝湖访问显示“加载遇到问题”
  8. SCVMM 2012 R2---安装Hyper-V Server 2012 R2主机服务器
  9. 牛皮凉席不好的原因!
  10. 手机怎么设置腾达路由器后显示远端服务器,教你如何用手机快速设置腾达路由器...