今天郭先生说一下WebWorker以及WebWorker在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经常发生在大量计算造成CUP阻塞的情况下,我们举一个例子,比如说我们制作了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);
}
}

脚本代码如下

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

下面是使用Web Worker

这里可以看出使用更多的线程可以很明显的提升CPU使用率。小伙伴们不妨打开线上案例亲自测试一下。

转载请注明地址:郭先生的博客

最新文章

  1. Leetcode Odd Even Linked List
  2. 简单的redis 性能测试
  3. swift 2.x学习笔记(一)
  4. [Hibernate] - Generic Dao
  5. TCP_NODELAY 和 TCP_CORK主要区别
  6. topcoder SRM 592 DIV2 LittleElephantAndPermutationDiv2
  7. HDU 1058 优先队列or堆
  8. javascript 获取HTML DOM父、子、临近节点
  9. 让progressDialog不会触摸消失
  10. 图片上传iOS
  11. 2013=10=19 ENGLISH 翻译
  12. DDD的&quot;waiting until GDB gets ready&quot;
  13. Qt限制文本框输入的方法(使用QRegExpValidator,为QLineEdit所独有)
  14. FORTH 安装使用
  15. callback function(回调函数) - 术语
  16. angularjs,Jsonp跨域访问页面
  17. 【nginx】大文件下载
  18. idea 提示忽略大小写
  19. Microsoft Dynamics CRM 2011 新建实体 需要注意的细节
  20. C#,一些非常简单但应该知道的知识点

热门文章

  1. 第7.16节 案例详解:Python中classmethod定义的类方法
  2. 第7.23节 Python使用property函数定义属性简化属性访问的代码实现
  3. PyQt(Python+Qt)学习随笔:QAbstractScrollArea的用途
  4. PyQt(Python+Qt)学习随笔:部件的inputMethodHints属性
  5. MySQL Docker容器实例创建并进入MySQL命令行
  6. python zip()函数用法
  7. tensorflow GPU的使用
  8. java视频流的断点续传功能
  9. Panda Global 要点聚焦,区块链在数字医疗的落地应
  10. 将命令行提示符里的执行结果导出到text文件中