由于JavaScript是单线程的,当一段js代码执行耗时过久时,会有阻塞的情况出现。
web worker就是解决阻塞的一种方式。它开启了一个一个worker thread,将复杂计算放在worker线程中运行,将同步代码转换为异步代码。
可以看这个例子。
main thread同步方式:
const btn = document.querySelector('button');
btn.addEventListener('click', () => {
let myDate;
for(let i = 0; i < 10000000; i++) {
let date = new Date();
myDate = date
}
console.log(myDate);
let pElem = document.createElement('p');
pElem.textContent = 'This is a newly-added paragraph.';
document.body.appendChild(pElem);
});
main thread和worker thread异步方式:
const btn = document.querySelector('button');
const worker = new Worker('worker.js');
btn.addEventListener('click', () => {
worker.postMessage('Go!');
let pElem = document.createElement('p');
pElem.textContent = 'This is a newly-added paragraph.';
document.body.appendChild(pElem);
});
worker.onmessage = function(e) {
console.log(e.data);
}
worker.js
onmessage = function() {
let myDate;
for(let i = 0; i < 10000000; i++) {
let date = new Date();
myDate = date
}
postMessage(myDate);
}
web worker解决什么问题?
由于JavaScript是单线程的,当一段js代码执行耗时过久时,会有阻塞的情况出现。 web worker就是解决阻塞的一种方式。它开启了一个一个worker thread,将复杂计算放在worker线程中运行,将同步代码转换为异步代码。
可以看这个例子。
main thread同步方式:
main thread和worker thread异步方式:
worker.js
vue-cli3 项目配置( webpack4 worker-loader2 )
手上项目测试demo( webpack3 worker-loader1 )
安装和配置
这是因为worker-loader2.0.0移除了对webpack3的支持,而work-loader1.1.1既支持w3也支持w4。可查看worker-loader release日志。
demo测试
worker线程
main线程
手上项目web worker 实践(迁移热力图计算逻辑)
安装和配置与上面一致。
工作线程
主线程
但是添加工作线程之后,自身体感功能有如下变化:
经过性能分析工具分析之后,有如下分析:
总结与思考
失败就真的没有收获吗?
做了一次web worker在项目上的尝试,虽然失败但也是经验的积累。 学到了如何配置webpack的worker-loader;主线程与工作线程之间如何进行数据传递;主线程在控制台的sources面板会开启一个独立的工作线程。
web worker应用场景探索
web worker的应用场景据说包括光线追踪(Ray Tracing),加密,数据预获取,Progressive Web App,拼写检查。
其他选项与业务场景脱离,但是数据预处理方面在项目中是可以实践的。
引用一段How JavaScript works: The building blocks of Web Workers + 5 cases when you should use them 中的话
数据预处理方面我想可以结合IndexedDB,localStorage等前端存储(可以用到localForage去择优选择前端存储)去做一些数据的预加载,比如图片,音频,视频等静态资源的预加载,通过工作线程默默地用户无感知地将资源缓存到本地,提升用户体验。其实主要是预先存储一些大块的内容,暂时不用但是后续会用到的。
有机会可以做一些实践尝试。