今天郭先生說一下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使用率。小夥伴們不妨開啟線上案例親自測試一下。
轉載請註明地址:郭先生的部落格