Upgrade to Pro — share decks privately, control downloads, hide ads and more …

What the Web Worker

What the Web Worker

隨著Web Application的發展,前端開發越來越複雜,多執行緒的需求也慢慢浮現,本議題主要介紹何謂Web Worker,到底能做到什麼,不能做到什麼,以及實際案例的分享。

Bingo Yang

May 18, 2013
Tweet

More Decks by Bingo Yang

Other Decks in Programming

Transcript

  1. About Me • front-end Engineer at • http:/ /blog.blackbing.net •

    [email protected] • https:/ /www.facebook.com/blackbing 2 Sunday, May 19, 13
  2. In the beginning 4 if (heard?) if (heard? && used?)

    if (heard? && used? && frustrated?) if (heard? && used? && used_in_project?) Sunday, May 19, 13
  3. Web Worker A web worker, as defined by the World

    Wide Web Consortium (W3C) and the Web Hypertext Application Technology Working Group (WHATWG), is a JavaScript script executed from an HTML page that runs in the background, independently of other, user- interface scripts that may also have been executed from the same HTML page. Web workers are able to utilize multi-core CPUs more effectively. http://en.wikipedia.org/wiki/Web_worker 5 Sunday, May 19, 13
  4. Web Worker 6 http://en.wikipedia.org/wiki/Web_worker A web worker, as defined by

    the World Wide Web Consortium (W3C) and the Web Hypertext Application Technology Working Group (WHATWG), is a JavaScript script executed from an HTML page that runs in the background, independently of other, user- interface scripts that may also have been executed from the same HTML page. Web workers are able to utilize multi-core CPUs more effectively. Sunday, May 19, 13
  5. UI Blocking? • javascript is single-threaded • UI rendering •

    executing javascript 8 http://www.nczonline.net/blog/2010/08/10/what-is-a-non-blocking-script/ Sunday, May 19, 13
  6. That’s easy! function getsum(max) { var cnt = 0; var

    sum = 0; while (cnt <= max) { sum += cnt++; } return sum; } 10 Sunday, May 19, 13
  7. Don’t jump into Web Worker for using Web Worker. 17

    If you just think it’s cool ,you’ll be frustrated. Sunday, May 19, 13
  8. Expectation 19 It should be faster. It should be easy

    to use. It should avoid blocking UI. Sunday, May 19, 13
  9. new Worker var worker = new Worker('worker.js'); worker.postMessage(something); worker.onmessage =

    function(e) { console.log('Worker said: ', e.data); }); 24 self.onmessage = function(e) { self.postMessage(e.data); }; Master Worker Sunday, May 19, 13
  10. var worker = new Worker('worker.js'); worker.postMessage(something); worker.addEventListener('message', function(e) { console.log('Worker

    said: ', e.data); }, false); 25 self.addEventListener('message', function(e) { self.postMessage(e.data); }, false); Master Worker new Worker Sunday, May 19, 13
  11. Worker cannot access • window • DOM • document •

    parent is undefined is undefined is undefined is undefined 26 Sunday, May 19, 13
  12. postMessage 28 worker.postMessage({ 'number': 1234, 'reg': /[\d]+/ig, 'boolean': true, 'object':

    { 'foo':'bar' }, 'array': ['foo','bar'] }) Master Sunday, May 19, 13
  13. postMessage 29 worker.postMessage({ 'number': 1234, 'reg': /[\d]+/ig, 'boolean': true, 'object':

    { 'foo':'bar' }, 'array': ['foo','bar'], 'func': function(){ //this is a function } }) Master Sunday, May 19, 13
  14. Worker can use • navigator • location(read-only) • XMLHttpRequest •

    setTimeout/setInterval • Basic Javascript data Structure and Function(Math, Date, Array, etc.) 31 Functions available to workers : https://developer.mozilla.org/en-US/docs/DOM/Worker/Functions_available_to_workers Sunday, May 19, 13
  15. Use Case Prefetching and/or caching data for later use •

    Code syntax highlighting or other real-time text formatting • Spell checker • Analyzing video or audio data • Background I/O or polling of web services • Processing large arrays or humungous JSON responses • Image filtering in <canvas> • Updating many rows of a local web database 37 Sunday, May 19, 13
  16. front-end is more and more • upload image: resize/rotate/filtering •

    upload/download file format: use a format for the server, translating other format in client side. 38 powerful Sunday, May 19, 13
  17. Background tasks run while user interacting • auto save the

    draft of article • syntax highlighting • log user’s behavior(mouse tracking, clicking, etc...) • prefetching data • predicting user behavior • Generate complicated html template 41 Sunday, May 19, 13
  18. Real world usage • Syntax highlighting : ace code editor(Bespin)

    • Crypto : SHA1 Checksum Calculator • Graphics/image • snowCam • arborjs: http:/ /arborjs.org/ • A User-Driven Web OS: http:/ /grimwire.github.io/grimwire • parallel.js: http:/ /adambom.github.io/parallel.js/ • Post huge data to server 43 Sunday, May 19, 13
  19. Brief Summary • What is web worker? • Basic usage

    • onMessage/postMessage • Debug • Use case and real world usage 45 Sunday, May 19, 13
  20. Known Issue • create worker in worker, but it is

    currently not support in Chrome • Crash when trying to use many Webworkers 46 Sunday, May 19, 13
  21. Break dependency 48 worker = new Worker('/worker_path/my_worker.js'); define (require)-> require

    'jquery' car = require 'lib/car' plane = require 'lib/plane' break requirejs dependency Master Sunday, May 19, 13
  22. inline Worker 49 var jscontent = require('text!workerScript/inline_worker.js'); var blobWorker =

    new Blob([jscontent], {type:'application/javascript'}); var blobWorker_url = URL.createObjectURL(blobWorker); URL.revokeObjectURL(blobWorker_url); inlineWorker.terminate(); var inlineWorker = new Worker(blobWorker_url); require text plugin Master Release resource Sunday, May 19, 13
  23. Troublesome on postMessage 51 var worker = new Worker('worker.js'); worker.postMessage({'type':

    'task1', data:'blabla'}); worker.postMessage({'type': 'task2', data:'blabla'}); worker.postMessage({'type': 'task3', data:'blabla'}); .... self.addEventListener('message', function(e) { var data = e.data; var type = data.type; if(type === 'task1') //blablabla else if(type === 'task2') //blablabla //......etc }, false); Master Worker Sunday, May 19, 13
  24. Passing Massive Data 52 worker.postMessage({ //it is a very very

    complicated JSON }) Worker UI still block! Master Sunday, May 19, 13
  25. Transferable Object 55 worker.postMessage({ 'number': 1234, 'reg': /[\d]+/ig, 'boolean': true,

    'object': { 'foo':'bar' }, 'array': ['foo','bar'], 'ref_object': object_from_closure, }) worker.postMessage('this is a string'); Worker structured cloning Freeeeze!! Master Sunday, May 19, 13
  26. pass Transferable Object 56 worker.postMessage(arrayBuffer, [arrayBuffer]); var SIZE = 1024

    * 1024 * 32; // 32MB var arrayBuffer = new ArrayBuffer(SIZE); var uInt8View = new Uint8Array(arrayBuffer); var originalLength = uInt8View.length; for (var i = 0; i < originalLength; ++i) { uInt8View[i] = i; } worker.postMessage(uInt8View.buffer, [uInt8View.buffer]); Master Sunday, May 19, 13
  27. Feature Detection 57 var ab = new ArrayBuffer(1); worker.postMessage(ab, [ab]);

    //If the buffer is transferred and not copied, its .byteLength will go to 0: if (ab.byteLength) { alert('Transferables are not supported in your browser!'); } else { // Transferables are supported. } http://updates.html5rocks.com/2011/12/Transferable-Objects-Lightning-Fast Master Sunday, May 19, 13
  28. Expectation? 58 It must be faster. It should be easy

    to use. It should avoid blocking UI. Cost of creating Worker Hardly to set up dependency if we need to pass massive data Sunday, May 19, 13
  29. 62 console console.log/error/time/etc... require([ "./car" "./wheel" ], (Car, Wheel) ->

    car = new Car('red') wheel = new Wheel('iron') ) require Worker Worker Benefits Sunday, May 19, 13
  30. Example 63 jscontent = require('text!inline_worker.js') $('#sum_with_worker').on('click', -> loading() worker =

    new WorkerD(inlineWorker_js) worker.send('getSum', sumMax) worker.on('gotSum', (event, data)-> log "gotSum: #{data}" loaded() ) ) @on "getSum", (max) -> sum = cnt = 0 while(cnt<=max) sum += cnt++ self.send('gotSum', sum) Master Worker Sunday, May 19, 13
  31. console 64 @on "getSum", (max) -> console.group 'getSum' console.time 'getSum'

    console.log 'getSum' console.log max sum = cnt = 0 while(cnt<=max) sum += cnt++ console.log sum self.send 'gotSum', sum console.log 'inlineWorker send message' console.timeEnd 'getSum' console.groupEnd 'getSum' Worker Sunday, May 19, 13