Running in Parallel: WebAssembly, Web Workers and Worklets

Running in Parallel: WebAssembly, Web Workers and Worklets

UI is freezing, one of the CPU cores burning, you can do nothing at the moment. The only thing you can hear right now is the howl cooler. The single perception you can feel is hot as a hell metal case of the laptop. This is not a horror story or a thriller – this is a modern web app that runs everything in the main JS thread.

We should use the benefits of parallel computing to make the user feel like in a rainbow paradise instead of a nightmare. We have all the powers to execute the code in parallel and keep the main thread ready to interactions. With modern features like Web Workers, WebAssembly, and Worklets, this is not true anymore. I want to share the experience running jobs in parallel on real examples, that could be adapted to your requirements.

4f0880beebecf17d29eb709246055e14?s=128

Vitalii Bobrov

November 26, 2019
Tweet

Transcript

  1. Running in Parallel Web Workers, Worklets and WebAssembly

  2. Running in Parallel All the Buzz Words, I ever heard

  3. Running in Parallel The Way to Performance

  4. Vitalii Bobrov • Lead SW Engineer @ EPAM • Angular

    Wrocław organizer • Performance warrior @bobrov1989 https://bobrov.dev
  5. Topics • Parallel Computations • Web Workers • Worklets •

    Web Assembly & AssemblyScript
  6. Parallel Computations

  7. Border Control

  8. Passport Control Border Line One Thread

  9. Passport Control Border Line One Thread

  10. Passport Control Border Line One Thread

  11. Passport Control Border Line Async

  12. Passport Control Border Line Async

  13. Passport Control Border Line Async

  14. Passport Control Border Line Async

  15. Passport Control Border Line Async

  16. Parallel doesn’t mean X times faster

  17. Passport Control Border Line Multi Thread Passport Control Line

  18. Passport Control Border Line Multi Thread Passport Control Line

  19. Passport Control Border Line Multi Thread Passport Control Line

  20. Thread is not equal to CPU core

  21. All Passports Border Line Worker / Worklet EU Passports Line

  22. All Passports Border Line Worker / Worklet EU Passports Line

  23. All Passports Border Line Worker / Worklet EU Passports Line

  24. Complicate Code

  25. Web Workers

  26. UI Blocking

  27. Disappointed User

  28. const worker = new Worker('path/to/worker.js'); Init Web Worker

  29. Full-Duplex Communication Main Thread Worker Thread worker.postMessage('data'); worker.addEventListener('message', (event: MessageEvent)

    => { console.log(event.data); }); addEventListener('message', (event: MessageEvent) => { console.log(event.data); }); postMessage('response');
  30. Worker implementation addEventListener('message', ({ data }) => { data.sort((a, b)

    => { for (let i = 0; i < 10000; i++) { const sum = i * Math.random() * 10; } return a.order - b.order; }); postMessage(data); });
  31. Off-thread

  32. Worklets

  33. Available Worklets • Paint • Animation • Layout • Audio

  34. Paint API

  35. Half-Duplex Communication Main Thread Worklet Thread class CirclesPainter { static

    get inputProperties() { return [ '--circles-offset', '--circles-count', '--circles-opacity' ]; } } element.style .setProperty('--circles-offset', 10);
  36. Half-Duplex Communication Main Thread Worklet Thread class CirclesPainter { static

    get inputProperties() { return [ '--circles-offset', '--circles-count', '--circles-opacity' ]; } } :root { --circles-count: 2; --circles-offset: 10; --circles-opacity: 1; }
  37. Create Worklet class MyPaint { paint(ctx: CanvasRenderingContext2D) { ctx.beginPath(); ctx.arc(x,

    y, outerRadius, 0, Math.PI * 2, false); ctx.arc(x, y, innerRadius, 0, Math.PI * 2, true); ctx.fill(); } } registerPaint('my-paint', MyPaint);
  38. Load Worklet if ('paintWorklet' in CSS) { CSS.paintWorklet.addModule('my-paint'); }

  39. Use Worklet .circle { background: #999 paint(my-paint); }

  40. QR Code

  41. Chart

  42. WebAssembly

  43. WASM - binary instruction format for a stack-based VM

  44. WHAT ?!

  45. WTF ?!

  46. WAT WebAssembly Text Format

  47. Devs are Good in Naming

  48. Available Options • Rust • C/C++ • TypeScript via AssemblyScript

  49. Install npm install assemblyscript

  50. Init npx asinit .

  51. Build npm run asbuild

  52. Basic function import 'allocator/tlsf'; export function add(a: i32, b: i32):

    i32 { return a + b; }
  53. Load WASM module import { instantiateStreaming, ASUtil } from 'assemblyscript/lib/loader';

    interface MyApi { add(a: number, b: number): number; } const imports: any = {}; async function main(): void { var interop: ASUtil<MyApi> = await instantiateStreaming<MyApi>(fetch('../build/untouched.wasm'), imports); console.log("The result is:", interop.add(1, 2)); }
  54. Running in Parallel Performance of Heavy Tasks

  55. @bobrov1989 https://bobrov.dev Vitalii Bobrov