本文章同步刊載於IT邦幫忙
那些年,我們一起讓瀏覽器當掉的日子
昨天提到了 Worker 就像是主從式架構一樣,有要求才有產出,而前後端的任務切割,就是在將商業邏輯與頁面呈現區隔開來。但隨著專案越來越複雜,前端越來越包山包海,我們好像一直不斷的在挑戰瀏覽器一樣,在前端做更多更複雜的事情。
有了 Worker 之後,或許我們會開始回憶起「那些年,我們一起讓瀏覽器當掉的日子」。
回到主題,那麼到底有哪些情況會用到 Worker 呢?我們先來看看許多專家的說法:
Web Worker的使用案例
- 影像辨識
- 影音資料處理
- 大量資料運算
- 頻繁或大量的AJAX request
- 較複雜的字串比對或分析
- Local 端資料庫的存取
- File IO (File Reader/Writer API)
以往這些較複雜的運算可能都要透過 server 端來處理,既然前端都可以處理這些事情了,那我們就可以直接在前端處理這些複雜運算,可以再度的節省 server 端的使用。而 Server 端最重要的 Database ,加上 HTML5 LocalStorage 與 IndexDB 可以在前端建立資料庫,拿來做一些簡單的單機系統也會更加容易。
但是這些很複雜的案例,並不是每個專案都有機會碰到,因此我想討論一些更common的案例。
前端可以處理的,就不在後端做
例如上傳圖片,以前都是直接整個檔案直接丟到server端做 resize, crop等等,現在流行前端直接做好再丟到後端。
例如上傳/下載某種檔案支援格式(.txt, .xls, .blabla),server端只要統一好格式,由前端組好在上傳到server端即可。
使用者操作時的「偷偷」動作
使用者在頻繁的操作系統時,如果此時要做一些偷偷背景動作,例如偷偷背景存資料,偷偷背景上傳檔案,讓使用者感覺「Wow,好快速。」例如:「文章自動儲存機制」,「程式碼高亮化(syntax highlight)」等。因為使用者正在操作系統,任何一個動作中斷都會讓使用者覺得系統當掉。
反正重點就是:優化/節省 Server Side 的使用,搾乾 Client Side 的效能(偷笑)。當然,這只是討論,如果有更好的使用案例都歡迎分享。
實作
有了這些基礎概念之後,我們就可以開始實作了。然而在實作上,我很快就遇到第一個問題。通常會需要用到 Worker 來幫忙的,可能會是比較複雜的專案,但中大型專案可能會用到 CoffeeScript 來加速開發的速度,用 RequireJS 來管理模組間的相依性,如果將 Worker 的 script 拆出去,馬上就遇到 Dependency 的問題。舉例來說:
|
|
這樣的路徑就失去了用 requirejs 的優勢,破壞了整個專案的 dependency ,如果為了用 Web Worker 而搞砸專案架構,那可是得不償失的,不過幸好,山不轉路轉。
Inline Worker
在 new Worker 時,丟進 Worker 的參數是一個路徑,那麼我們就可以動態產生一個 blob url 路徑,傳給Worker ,動態產生 Woker。
|
|
如上,我們就可以動態用 content 來建立 inlineWorker 。只要確保 content 的產生是沒有問題的,用 string 的方式將它讀入就可以建立 Worker。
另外 requireJS 也支援在 worker 裡頭使用,當你的 Worker 要做的事情很多時,可以用 RequireJS 來進行管理,參考requireJS webworker
Debug
Worker 裡頭沒有好用的 console 可以用,不過有 error 的 event 可以註冊。例如:
|
|
另外也可以在 developer tool 裡頭的「Source」開啟「Workers: Pause on start」
引用外部程式
Worker 是否可以引用外部程式? 答案是可以的,但需要注意的是它的限制是無法存取瀏覽器資源,所以跟 browser 相關的 API 例如 DOM 都不能用,所以不能使用 jQuery , Backbone 這種與 Browser 相依性很高的 Library (廢話)。
|
|
值得一提的是,
或是直接在 Worker 裡頭自己主動結束
|
|
其他
Worker 其實還定義了 Shared Worker ,可以在不同頁面共享 Worker 的資源,在此不介紹是因為我想不到有比較有意義的應用,有興趣深入瞭解的朋友可以參考 The Basics of Web Workers,裡面有基本的用法介紹。
Just do it
Web Worker 的 API 其實很簡單,難的是在實作上如何將這些動作拆開。建議可以慢慢的將一些動作移到 Worker 來處理,例如 AJAX request ,將資料處理與頁面 render 的程式分開。慢慢的就會更容易的掌握它。
不過不要以為 Web Worker 就這樣結束了,這篇文章其實只是個起點,實際應用在專案上,還會遇到很多問題(嘿嘿~),有任何問題都歡迎提出討論喔 ,我們 2013 JSDC 見。
廣告時間
「影分身好威喔!我也想要!」
HTC One 的 Camera 也可以快速建立多重影分身
參考資料
- http://dev.w3.org/html5/workers/
- https://developer.mozilla.org/en-US/docs/DOM/Using_web_workers?redirectlocale=en-US&redirectslug=Using_web_workers
- http://blog.teamtreehouse.com/using-web-workers-to-speed-up-your-javascript-applications
- http://ejohn.org/blog/web-workers/
- http://www.html5rocks.com/en/tutorials/workers/basics/
- http://debuggable.com/posts/run-intense-js-without-freezing-the-browser:480f4dd6-f864-4f72-ae16-41cccbdd56cb
- http://stackoverflow.com/questions/2773682/what-are-the-use-cases-for-web-workers
- http://html5hacks.com/blog/2012/09/22/web-workers-basics-of-the-web-browsers-ui-thread/
- http://www.html5rocks.com/en/tutorials/workers/basics/#toc-enviornment-subworkers
- http://blogs.msdn.com/b/ie/archive/2011/07/01/web-workers-in-ie10-background-javascript-makes-web-apps-faster.aspx
- http://blogs.msdn.com/b/davrous/archive/2011/07/15/introduction-to-the-html5-web-workers-the-javascript-multithreading-approach.aspx
- http://msdn.microsoft.com/en-us/hh549259.aspx
- http://stackoverflow.com/questions/11871452/can-web-workers-utilize-100-of-a-multi-core-cpu?rq=1
- http://www.smartjava.org/content/html5-easily-parallelize-jobs-using-web-workers-and-threadpool