一般,瀏覽器執行某段程序的時候會阻塞直到運行結束後在恢復到正常狀態,而HTML5的Web Worker就是爲了解決這個問題。經過worker線程完成密集計算,避免程序的阻塞和頁面的卡頓(fps太低)html
用fibonacci數列來模擬測試web
worker-test.htmlajax
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>測試 web worker</title> </head> <body> <script> function fibonacci(n) { return n < 2 ? n : arguments.callee(n - 1) + arguments.callee(n - 2); } function testNoWorker() { let start = Date.now(); fibonacci(38); let end = Date.now(); console.log(end - start); // wait a long time.. } function testUseWorker() { let start = Date.now(); let worker = new Worker('worker.js'); worker.postMessage(38); worker.addEventListener('message', function (event) { let end = Date.now(); console.log('worker result: ', end -start); }); console.log('can do other jobs, when worker is computing'); } testNoWorker(); testUseWorker(); </script> </body> </html>
worker.jsjson
function fibonacci(n) { return n < 2 ? n : arguments.callee(n-1) + arguments.callee(n-2); } self.addEventListener('message', function (event) { let result = fibonacci(event.data); self.postMessage(result); }); // 可用 setTimeout , setInterval setTimeout(() => { console.log('timeout..'); }, 100); setInterval(() => { console.log('setInterval...'); }, 200); // 可發起ajax fetch('data.json').then(res => res.json()).then(data => {console.log(data, '<--json data')}); // 可訪問 location, navigator console.log(location); console.log(navigator); // worker.js的執行上下文爲 self (worker實例), // self上的屬性和方法可直接調用 console.log(typeof addEventListener); console.log(typeof postMessage);
假設主頁面須要屢次執行耗時的操做(如: fibonacci), 可以下用worker來異步執行.跨域
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>測試 實例化多個 web worker</title> </head> <body> <script> function fibonacci(n) { let start = Date.now(); let worker = new Worker('worker.js'); worker.addEventListener('message', function (event) { let end = Date.now(); console.log('worker result: ', end - start); }); worker.postMessage(n); } /* 同時跑多個worker, 會下降每一個worker線程的性能;但總比阻塞頁面要好 */ fibonacci(38); console.log('after one'); fibonacci(38); console.log('after two'); fibonacci(38); console.log('after three'); console.log('can handle other jobs..'); </script> </body> </html>
在主頁面實例化worker, new Worker('/url/to/worker.js')
worker腳本必須和主頁面同域;在worker腳本中,能夠 self.importScripts('url/to/script.js')
導入任何域的腳本, 多個 self.importScripts()
是順序同步加載的瀏覽器
worker.terminate()
終止worker線程