web worker是js中启动的子线程,不能操作dom和windows对象,但是可以执行ajax,处理复杂数据,如二进制blob数据,或者websocket连接,worker和主线程通过postMessage和onmessage进行通信。
本文不是主要介绍worker,主要讲webpack中如何使用web worker
webpack中提供了一个loader叫做worker-loader,用来实现web worker的功能。
第一步需要install worker-loader
npm i -D worker-loader
然后在webpack配置文件中配置worker-loader的使用
{ module: { rules: [ { test: /\.worker\.js$/, use: { loader: 'worker-loader' } } ] }}
这是worker-loader就会对结尾为”worker.js“的文件进行编译。
比如我们有一个alertworker.js文件用来执行websocket的连接
self.onmessage=function(e){ let data = e.data; init(); } let socket=null; function init(){ socket = new WebSocket("ws://192.168.0.3:8009/socket/socketpush"); socket.onopen = function (msg) { //do something } socket.onmessage = function (msg) { self.postMessage(msg); } }
然后在主线程文件中我们就可以如下方式启动worker线程
import MyWorker from './alertworker.js' let worker=new MyWorker(); worker.postMessage("start");//主线程向子线程传递数据 worker.onmessage=(msg)=>{ //接收子线程传递来的数据,并渲染到页面上。 }
通过使用worker-loader我们可以在webpack自动化开发中方便的使用webworker来提供页面的性能。
经实际项目中测试,websocket连接从主线程中移到worker子线程中后,页面性能明显提升,并且解决了websocket高频率推送数据时页面假死的问题。
worker不只可以用到websoket连接中,还可以用到大文件上传的功能中,以此来提高页面的用户体验度。火狐所开发的用于pdf在页面中渲染的pdfjs中,对于pdf的数据解析也是采用了在worker中处理的方案。
在不使用worker的情况下,js是单线程的,那么即使是ajax请求,websocket推数据,都会影响页面的渲染和重绘,以至页面事件的响应。如果页面的某项操作与页面dom无关,并且耗时较长,那么就可以把它通过worker来执行,以此来解放页面的渲染和事件循环。