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

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.

Vitalii Bobrov

November 26, 2019
Tweet

More Decks by Vitalii Bobrov

Other Decks in Programming

Transcript

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

    Wrocław organizer • Performance warrior @bobrov1989 https://bobrov.dev
  2. 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');
  3. 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); });
  4. 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);
  5. 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; }
  6. 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);
  7. 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)); }