背景
在项目业务开发中,使用js计算了可视化图的布局,这需要一定的js执行耗时,影响了用户操作。因此我找到了Web Worker。
Web Worker是什么
Web Worker 是 HTML5 引入的一个新特性,允许开发者在浏览器后台运行 JavaScript,而不会阻塞页面的渲染或用户的交互。它运行在与主线程不同的全局上下文中。这意味着它有自己的内存和全局变量,不能直接访问主线程的 DOM 或全局变量。但是,它可以与主线程进行通信,通过发送和接收消息来交换数据。
Web Worker使用理由
在单线程的 JavaScript 环境中,所有的代码都运行在同一个线程中,包括 UI 渲染、事件处理、脚本执行等。当某个任务(如大量的数据处理或复杂的计算)需要花费很长时间时,它会阻塞主线程,导致页面无法响应用户的交互或进行渲染。这不仅降低了用户体验,还可能导致浏览器崩溃。
带来的好处:
-
提高应用响应能力:主线程被独占执行一些耗时的计算或操作时,会导致UI无响应。WebWorker 可以把这些任务转移到后台线程,从而保证主线程的运行,提高应用的响应能力。
-
充分利用多核CPU:现代CPU都是多核的,WebWorker 可以让 Web 应用利用多核 CPU 的并行计算能力,充分发挥计算机硬件性能。
-
避免渲染阻塞:JavaScript 运行在主线程,如果主线程一直占用,就无法执行 GUI 渲染任务,导致界面渲染受阻。WebWorker 把一些费时任务分流到后台线程就可以避免这一问题。
-
后台持续运行:Web Worker 所在后台线程可持续运行,即使页面被挂起或最小化,任务仍在后台执行,非常适合一些需要长时间运行的操作。
实践
使用 Web Workers 非常简单。首先,你需要创建一个新的 Worker 对象,并传入一个包含要在后台运行的 JavaScript 代码的 URL。然后,可以通过 postMessage() 方法向 Worker 发送数据,并通过 onmessage 事件监听器接收 Worker 返回的数据。
js
// 主线程
const countWorker = new Worker("count.worker.js");// 创建一个新的 Worker 对象
btn.addEventListener("click", () => {
countWorker.postMessage(1);// 向 Worker 发送数据
});
countWorker.onmessage = function (e) {
console.log(e.data);// 处理 Worker 返回的数据
};
// count.worker.js
self.onmessage = function(event) {
console.log('主线程发送的数据:', event.data); // 处理主线程发送的数据
/* 执行一些耗时的计算 */;
const sTime = Date.now();
let num = event.data;
while (Date.now() - sTime < 10000) {
num++;
}
self.postMessage(num); // 将结果发送回主线程
};
应用场景
- 复杂的计算:如图像处理、大数据分析等。
- 数据密集型任务:如实时通信、WebSocket 数据处理等。
- 长时间运行的任务:如文件上传、下载、转码等。
- 动画和游戏:需要高帧率和平滑渲染的场景。
最后
Web Worker 可以帮助我们解决单线程 JavaScript 带来的性能问题。将它用于处理耗时的任务,我们可以让主线程保持流畅,提高用户体验。虽然它有一些限制(如不能直接访问 DOM),但只要我们合理利用它,就可以为我们的网页应用带来显著的性能提升。