three.js中使用Web Worker进行多线程计算与性能测试

作者:极速慢跑

时间:2026-10-24

浏览:651

本文详解在three.js中利用Web Worker解决JavaScript单线程阻塞问题。通过对比1000个Mesh在大量位置计算下的FPS表现,展示Web Worker如何保持主线程流畅。测试数据显示,即使计算量增加,使用Web Worker仍能将FPS稳定在60左右,显著提升CPU利用率与渲染性能。

文章目录

前言

本文介绍Web Worker及其在three.js中的应用。JavaScript默认是单线程执行,这意味着运行JS代码时UI渲染会暂停,对于拥有多核CPU的电脑而言,这种单线程限制显得不够高效。Web Worker的出现部分解决了这一问题。根据官方定义,Web Worker允许脚本创建后台任务,任务执行期间可与创建者进行通信。创建Worker只需调用Worker(URL)构造函数,参数URL指向指定的脚本文件。更多关于Web Worker的知识可查阅相关文档。线性案例请参考web-worker链接。

1. 在three.js中使用多线程

在three.js中引入Web Worker通常是为了解决大量计算导致的CPU阻塞问题。例如,假设创建了1000个Mesh对象,

前言

若仅让它们进行简单的运动,CPU压力很小,FPS可维持在60左右。但如果这1000个Mesh的位置需要通过大量计算得出,FPS会显著降低(与计算量呈负相关)。以下是一段示例代码:


for(let i=0; i<num; i++) {
 let angle = positions[i].y / (1000 / (Math.PI * 10));
 positions[i].x = positions[i].x + Math.sin(angle);
 positions[i].z = positions[i].z + Math.cos(angle);
 positions[i].y = positions[i].y + 1;
		//上面就是简单的位置变化,下面的代码模拟复杂的变化,累加100000次(这是非常占用线程的情况)
 for(let j=1, total=1; j<=100000; j++) {
 total += j;
 }
 if(positions[i].y > 500) {
 positions[i].y = positions[i].y - 1000;
 }
}
for(var i=0; i<num; i++) {
 group.children[i].position.set(positions[i].x, positions[i].y, positions[i].z);
}

positions数组存储了1000个Mesh的位置信息,group包含所有Mesh。每次渲染时更新positions数组,并将新值赋给Group中的每个Mesh。这种情况下,FPS可能低至7FPS,场景转动时能明显感到卡顿。接下来使用Web Worker解决此问题,主线程代码如下:


myWorker = new Worker('/static/js/worker.js');
myWorker.postMessage(positions);
myWorker.onmessage = e => {
 let positions = e.data;
 for(var i=0; i<num; i++) {
 group.children[i].position.set(positions[i].x, positions[i].y, positions[i].z);
 }
}

Worker脚本代码如下:


onmessage = function(e) {
 let num = 1000;
 let positions = e.data;
 setInterval(e => {
 for(let i=0; i<num; i++) {
  let angle = positions[i].y / (1000 / (Math.PI * 10));
  positions[i].x = positions[i].x + Math.sin(angle);
  positions[i].z = positions[i].z + Math.cos(angle);
  positions[i].y = positions[i].y + 1;
  for(let j=1, total=1; j<=100000; j++) {
  total += j;
  }
  if(positions[i].y > 500) {
  positions[i].y = positions[i].y - 1000;
  }
 }
 postMessage(positions);
 }, 1000 / 60)
};

主要逻辑与未使用Web Worker时几乎相同,区别在于位置处理代码在新线程中执行。setInterval定时器每次完成位置计算后,通过postMessage(positions)将结果返回给主线程。主线程通过onmessage接收信息,返回对象的data属性即为新的positions数据。此时FPS可恢复至60左右,场景转动流畅,无明显卡顿。效果令人满意。

2. 性能分析

前文提到,每次位置计算中包含10万次累加操作。未使用Web Worker时,FPS降至7。以下是更多对比数据(数据仅供参考,实际表现与当前环境及配置有关)。


累加次数(万次) 使用Web Worker 未使用Web Worker
1 60 60
3 60 39
5 60 26
7 60 11
9 60 8
11 60 6

从数据可以看出,无论计算量多大,使用Web Worker均不影响主线程,而未使用时影响严重。下面展示两种情况下的电脑性能对比:

(未使用Web Worker)

前言

(使用Web Worker)

前言

由此可见,使用更多线程能显著提升CPU利用率。读者可打开线上案例亲自测试。

总结

至此,关于three.js中多线程使用及性能测试的文章介绍完毕。更多相关three.js多线程使用及性能测试内容,请搜索本站以往文章或继续浏览下方相关文章,希望大家以后多多支持本站!

版权声明:本文为郭志强的原创文章,转载请附上原文出处链接及本声明。原文链接:https://www.mrguo.link

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章