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

Running in Parallel: NgRx with WebAssembly, Web Workers and Worklets

Running in Parallel: NgRx with 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 only perception you can feel is as hot as a hell metal case of the laptop. This is not a horror story or a thriller. Just a modern web app that runs everything in the main JS thread. The only way to be alive - run code in parallel.

Vitalii Bobrov

May 27, 2019
Tweet

More Decks by Vitalii Bobrov

Other Decks in Programming

Transcript

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

    Wrocław organizer • Angular in Depth contributor • 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)); }