🧑🎓 个人主页:《爱蹦跶的大A阿》
🔥当前正在更新专栏:《VUE》 、《JavaScript保姆级教程》、《krpano》
✨ 前言
Web Worker可以将耗时任务放到后台执行,避免阻塞UI。本文将详细介绍Web Worker的用法,让你可以提升web应用性能。
通过本文你将学习:
- Web Worker的工作原理
- 不同类型worker的区别
- worker的创建和通信用法
- worker间的数据传递方法
- worker的调试技巧
- worker可以提升应用性能的场景
- 弥补worker在老浏览器不兼容的方法
准备让Web Worker成为你的网页优化利器了吗?让我们开始吧!
第一节:Web Worker简介
Web Worker可以将JS代码运行在后台线程,实现多线程:
- 不阻塞主UI线程,提升互动性
- 与主线程同时运行,实现并行
- 通过消息传递与主线程通信
DEDICATED WORKER:专属于一个页面 SHARED WORKER:可被多个页面共享
第二节:创建Worker
创建一个Dedicated Worker的基本步骤是:
- 主线程中用new Worker()实例化一个Worker对象,并传入脚本的路径
- 在指定的js脚本中使用self对象对worker进行编程
- self对象表示worker的全局作用域,可以添加事件监听器
- 常见的事件有onmessage、onerror等
一个典型的示例:
// 主线程
const worker = new Worker('work.js');
worker.postMessage('start');
// work.js
self.addEventListener('message', e => {
console.log('worker recv:', e.data);
self.postMessage('hello from worker');
});
Worker线程中不能直接访问DOM,但可以通过postMessage()与主线程通信。
创建一个Shared Worker步骤类似,只是用SharedWorker实例,并可以指定worker的名称。
Shared Worker可以被多个窗口访问,从而共享同一个逻辑。
Dedicated Worker专属于一个页面文档。根据实际需求选择合适的Worker类型。
创建shared worker:
// 主线程
const worker = new SharedWorker('work.js');
// work.js
self.addEventListener('connect', (e) => {
// 收到连接
});
第三节:worker间通信
主线程 -> worker:
worker.postMessage('hello');
worker -> 主线程:
self.postMessage('hi from worker');
- 主线程到worker的通信
主线程使用worker对象的postMessage()方法向worker发送消息:
// 主线程
worker.postMessage('start');
postMessage()可以发送各种数据类型,包括原始类型、对象、数组等。
- worker到主线程的通信
worker中使用self.postMessage()发送:
// worker内
self.postMessage('message from worker');
self代表worker的全局作用域。
- 接收消息
主线程通过worker.onmessage监听消息:
// 主线程
worker.onmessage = function(e) {
console.log(e.data);
}
worker中通过self.onmessage监听:
// worker内
self.onmessage = function(e) {
console.log(e.data);
}
e.data是消息内容。
- 传递数据注意事项
- 对象会串行化,记得调用JSON.parse()
- 传递函数需要把函数字符串化
这些是worker间通信的主要方式,可以传递不同类型的数据,充分利用多线程带来的好处。
第五节:Worker中的异步请求
Worker线程可以发出AJAX请求,使用与主线程相同的XMLHttpRequest对象:
// Worker内
const xhr = new XMLHttpRequest();
xhr.open('GET', '/data');
xhr.onload = () => {
self.postMessage(xhr.response);
}
xhr.send();
这样可以在Worker中完成异步数据加载,不影响主UI线程。
第六节:调试Worker
主线程可以通过inspect()调试运行中的Worker:
const worker = new Worker();
worker.inspect();
这会打开DevTools来调试worker线程。
也可以将console日志发送到主线程:
// Worker内
self.postMessage(console.log.apply(console, arguments));
第七节:使用场景
Worker常用于:
- 超大数据排序、搜索、处理
- 数据转换与编译,如Json、Excel
- 高延迟任务或高计算工作,如机器学习
第八节:兼容性和代替方案
低版本浏览器可能不支持Worker,可以使用polyfill或只在新浏览器使用。
也可以使用setTimeout模拟后台线程。
✨ 结语
在这篇文章中,我们全面介绍了Web Worker的用法 - 它可以将JavaScript代码运行在后台线程,实现多线程计算。
首先,我们看到Web Worker的优点,它不会阻塞主UI线程,可以实现并行执行任务。然后,我们介绍了Dedicated Worker和Shared Worker的区别,以及创建和终止Worker的方法。
接下来,我们重点讲解了Worker之间的消息通信机制,这是利用多线程的关键。我们也讨论了Worker中发起异步请求和调试技巧。
最后,给出了Web Worker的实际应用场景,以及需要注意的兼容性问题。
我尽量用通俗的语言和示例给出了全面的讲解,希望这篇文章可以帮助大家正确使用Web Worker来优化web应用性能。如果还有任何问题,欢迎在评论交流!