Chrome瀏覽器中的JavaScript多線程---WebWorker

  瀏覽器中的JavaScript是單線程執行的,如果遇到重量級的計算任務時,一般需要運行很長時間,這樣就會造成UI任務來不及響應,帶來不好的用戶體驗。那麼如何在JavaScript中使用多線程來解決這類問題呢?HTML5引入了新的Web Worker API,它讓一段JavaScript程序運行在主線程之外的另外一個線程或進程中。Chrome對Web Worker API也有了基本的支持,在Android平臺上雖然還存在缺陷,但是不影響基本使用。

先介紹一下Web Worker的基本知識

Web Worker有兩種,一種是常見的Dedicated Worker,在JavaScript中簡寫爲Worker,例如:var worker = new Worker(“source/worker.js”); 該例中worker.js就運行在另外一個線程中,無論計算任務有多重都不會直接阻塞主線程中的UI。另外一種是SharedWorker,它在瀏覽器中只有一個運行實例,允許所有的頁面共享使用。關於Web Worker更多的介紹,請參考W3C的API文檔http://dev.w3.org/html5/workers/

現在大家可能會問,現在引入了多線程,那如何保證Worker線程和主線程的同步呢?如果Worker線程和主線程同時修改了頁面中的某個節點,豈不是會產生髒數據?這個不用擔心,因爲Worker線程不能直接訪問和操作頁面中的DOM屬性,如果Worker線程需要訪問頁面中的某個DOM節點,必須通過postMessage API發消息給主線程,主線程在收到消息後獲取頁面中的某個DOM節點的屬性,再通過postMessage的方式回傳給Worker線程,這樣就避免了上述問題。

下面介紹一下WebWorker在Chrome中的實現

Chrome瀏覽器使用的是多進程架構,即Browser進程和Render進程,一般情況下,打開一個頁面時,瀏覽器就爲其分配一個進程,稱爲Render進程,Blink(以前的WebKit)就運行在Render進程中,當然了JavaScript也就運行該進程中,我們稱WebKit和JS運行的線程爲渲染線程。

Worker(Dedicated Worker)只屬於某個頁面,不會和其他頁面的Render進程共享,所以Chrome在Render進程中創建一個新的線程來運行Worker中的JavaScript程序。

  對於SharedWorker來說,情況就發生了變化,由於SharedWorker是瀏覽器所有頁面共享的,不能採用與Worker同樣的方式實現,因爲它不隸屬於某個Render進程,可以爲多個Render進程共享使用,所以Chrome瀏覽器爲SharedWorker單獨創建一個進程來運行JavaScript程序,在瀏覽器中每個相同的JavaScript只存在一個SharedWorker進程,不管它被創建多少次。

由於Chrome需要爲SharedWorker創建新的進程,在Android平臺上就會存在一些困難,因爲Android畢竟是嵌入式平臺,Android Chrome對創建的進程所做了限定,假設限定9個進程,如果進程總數達到了9,就意味着用戶不能再打開新的標籤頁了。如果瀏覽器創建了太多的SharedWorker進程,那麼用戶或許根本連第二個標籤頁都打不開了。另外SharedWorker的優先級該如何確定,比前臺的標籤頁優先級小?或者比後臺的標籤頁優先級大?如果訪問SharedWorker的標籤頁都在後臺,優先級會變成怎樣?如果訪問SharedWorker的某個標籤頁在前臺,其優先級又該如何設定?這些因素足以說明Android平臺的特殊性,所以據寫文章爲止,在Android平臺上SharedWorker仍然處在討論階段,Chrome M30不支持該API。

發佈了31 篇原創文章 · 獲贊 133 · 訪問量 37萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章