性能优化!Web Worker开多线程使用方法

13 阅读1分钟

用途:JS是单线程语言,一些复杂的计算,可能会影响主线程的运行,造成堵塞,导致页面无法及时绘制,进而出现卡顿、短暂白屏现象等。为此,使用new Worker可以创建额外的线程来解决复杂的计算,计算完结果后再返回给主线程,从而提升性能。(注意不能操作dom元素)

1、创建文件夹workers,创建demo_worker.ts文件(代表1个线程)

文件路径src\workers\demo_worker.ts

// self,可以理解为当前线程实例对象
// onmessage 监听主线程是否有发送消息过来
self.onmessage = (e) => {
    console.log('主线程发送过来的数据', e.data)
    const { data } = e
    data.name = '小猪' //修改数据
    self.postMessage(data) //发送修改完后的数据给主线程
}

2、主线程上使用(即Vue组件文件)

文件路径src\views\Workers.vue

<template>
    <p>{{ workderData.name }}</p>
    <el-button @click="startWorker">开始工作</el-button>
    <el-button @click="stopWorker">停止工作</el-button>

</template>


<script setup lang="ts">
// vite 特有引入方式?worker
// vite官网原话:一个 web worker 脚本可以直接通过添加一个 ?worker 或 ?sharedworker 查询参数来导入。
// 默认导出一个自定义的 worker 构造器:
// import MyWorker from './worker?worker'
// const worker = new MyWorker()
import Worker from "@/workers/demo_worker?worker"
import { ref } from "vue"
const workderData = ref({
    name: '佩奇',
    age: 26
})
type W = InstanceType<typeof Worker>

let worker: W | null = null
  
const startWorker = () => {
    worker = new Worker() //创建线程实例对象
    worker.postMessage(JSON.parse(JSON.stringify(workderData.value))) //主线程发送数据给线程
  
  // 监听线程数据处理结果
    worker.onmessage = e => {
        console.log('线程完成', e)
        workderData.value = e.data
    }
}
const stopWorker = () => {
    (worker as W).terminate() //停止线程工作
}

</script>

<style scoped></style>

3、浏览器基本上都支持

Internet Explorer 10, Firefox, Chrome, Safari 和 Opera 都支持Web workers.

4、检测浏览器是否支持 Web Worker(实际项目可以不考虑,除非IE浏览器)

if (typeof (Worker) !== "undefined") {
  // 是的! Web worker 支持!
  // 一些代码.....
} else {
  //抱歉! Web Worker 不支持
}