webWorker是什么?
Web Worker是HTML5引入的浏览器多线程技术,允许在独立线程中执行后台任务,避免阻塞主线程从而提升Web应用性能。
为什么要使用Web Work?
浏览器渲染的js线程是单线程 这意味着各子任务的执行是串行的在同一时间内只能执行一个任务。当大量计算密集型/DOM操作的任务出现时阻塞UI。
初体验记录
在实现大文件计算MD5时考虑到提升性能时了解到Web Worker, 那么来看看在vue2项目中如何使用Web Worker的吧
栗子
编写一个独立的脚本
(如*.worker.js)定义对应的线程逻辑
js
handlerMsg(parames){
*****
return result
}
onmessage = function(e) {
const result = handlerMsg(e.parames)//模拟一个耗时任务
if(result){
//发送成功的信息
postMessage({ result: result, status: 'done' });
}else{
//发送错误
postMessage({ error:'error' ,status: 'error' });
}
};
线程使用
文件引入
- 将webWorker 脚本文件放置到pubilc文件夹下(注意: public 目录下的文件不会被 webpack 处理,所以你不能直接使用 ES6 的 import 语句来引入其他文件)
- 将webWorker 脚本文件放置src下的文件夹中则需要使用
worker-loader
重点描述下使用worker-loader
- 安装
worker-loader
js
npm i -D worker-loader
- 配置loader
确保在Webpack配置中正确处理了.worker.js文件的加载,你可能需要在Vue CLI的配置文件中添加一个规则来支持worker的导入
js
chainWebpack: config => {
****
config.module
.rule('worker')
.test(/\.worker\.js$/)
.use('worker-loader')
.loader('worker-loader')
.end();
// 解决:worker 热更新问题
config.module
.rule('js')
.exclude
.add(/\.worker\.js$/)
.end();
// 解决:"window is undefined"报错,这个是因为worker线程中不存在window对象,因此不能直接使用,要用this代替
config.output.globalObject('this')
},
在Vue组件中使用
js
import MyWorker from '../js/md5Worker.worker';
const worker = new MyWorker();
worker.postMessage({ parames: parames }); // 发送参数给worker处理
worker.onmessage = e => {
if (e.data.status === 'done') {
console.log('result:', e.data.result);
worker.terminate(); // 完成工作后终止worker
} else if (e.data.status === 'error') {
console.error('Error:', e.data.error); // 处理错误情况
worker.terminate(); // 终止worker以释放资源
}
};
注意事项
- 同源限制:Worker脚本需与主线程同源。
- 数据传输优化 :大文件建议使用Transferable Objects(如
ArrayBuffer)减少拷贝开销。 - 错误处理 :监听
worker.onerror捕获异常并处理。