关于在 vue 中使用 web worker 的一些问题

首先列出碰到的问题和答案好了好了:

1、如何在 vue 中加载 worker.js 文件:

  使用 worker-loader,并在 vue.config.js 文件中做出相应配置,具体规则参考正文

2、如何在 worker.js 中使用 import:

  如果使用 vue,那第一个问题就顺带解决了这个问题。

  如果不用,则需要在创建 Worker 对象的时候,第二个参数填写上 { type: 'module' }。例:new Worker('./worker.js', { type: 'module' })

3、如何将 worker 的 message 事件变成 async/await 

  使用 promise-worker 包,具体使用方式参考下方或者 npm 文档

前几天,测试给提了一个问题,说是在一个页面点击按钮后,界面会卡顿十几秒。我检查代码后发现,是加密信息时,加密内容过大,导致了程序卡顿,尝试降低了加密内容大小,将卡顿时间压缩到二到四秒。但是用起来还是怪怪的,突然想到从来没有用过的 worker,用这个不就可以不阻塞渲染进程了嘛,何不乘此机会用一次呢?于是便开始翻阅 MDN 的相关文档。

按照 MDN 的示例代码,我尝试编写完 worker.js,并调用了 new Worker('./worker.js'),但是控制台提示,找不到该文件,我上 stock overflow 查了查。一开始以为是没使用模块的问题,便尝试将 new Worker('./worker.js') 改成了 new Worker('./worker.js', { type: 'module' }),但是还是没用。

换了关键词后,发现可能需要使用 webpack 的插件加载 worker.js,便去翻了 webpack 4 的 worker loader 的使用方法。官方文档说,按照官方文档的最简配置,我修改了 vue.config.js,但是没有效果,便去 stock overflow 上搜索。试了几种方法后,最后发现可能需要先移除 js 规则检查,移除检查后,再次运行,便可以运行了。

解决了无法加载的问题之后,我便尝试获取 worker 线程的返回值了,看了看文档,发现,不能实现我想要的同步效果,便去找使用 promise 的 worker 包,然后就找到了 promise-worker。按照官方文档所述,代码终于成功运行了,可喜可贺可喜可贺。下面是示例代码: 

// vue.config.js
let config = {
  chainWebpack: (config) => {
    config.module.rule('js').exclude.add(/\.worker\.js$/).end()

    config.module
      .rule('worker')
      .test(/\.worker\.(c|m)?js$/i)
      .use('worker-loader')
      .loader('worker-loader')
      .options({
        inline: 'fallback',
      })
      .end();
  },
};
module.exports = config;

// example.worker.js
import { doEncrypt } from 'utils.js'
import registerPromiseWorker from 'promise-worker/register';
registerPromiseWorker(({ message }) => doEncrypt (message);

// example.js
import Worker from './example.worker.js';
const worker = new Worker()
const exampleWorker = new PromiseWorker(worker);
/**
 * 发布消息
 * @param {Object} wsClient
 * @param {string} message
 * @param {object} payload
 */
export const sendMessage = async (wsClient,message)=>{
    const encryptString = await exampleWorker?.postMessage({ message  }).catch((error) => console.error(error)))
    wsClient.send(encryptString)
}

 

posted @ 2022-11-04 14:13  FreezeNow  阅读(1318)  评论(0编辑  收藏  举报