useWorker() – Use Web Workers with React Hooks

useWorker() is a js library (with typescript support) that allows you to use the Web Worker Web API, through React Hooks. This library allows you to run the expensive function without blocking the user interface, using a simple syntax that makes use of Promise

import React from "react";
import { useWorker, WORKER_STATUS } from "@koale/useworker";

const numbers = [...Array(5000000)].map(e => ~~(Math.random() * 1000000));
const sortNumbers = nums => nums.sort();

const Example = () => {
  const [sortWorker, { status, kill }] = useWorker(sortNumbers);
  const runSort = async () => {
    const result = await sortWorker(numbers); // non-blocking UI
    console.log("End.");
  };
  return (<button type="button" onClick={runSort}> Run Sort</button>);
};

Installation per NPM/Yarn:

npm install --save @koale/useworker

useWorker()
useWorker() Source (GitHub) →

πŸ€” Unfamiliar with Web Workers? Check out Handling JavaScript events with Web Workers then!

Handling JavaScript events with Web Workers

Alex MacArthur:

The advantages of Web Workers are many, but things really clicked for me when it came to the several DOM event listeners in any given application. These all necessarily live on the browser’s main thread, and if that thread is congested by a long-running process, the responsiveness of those listeners begins to suffer, stalling the entire application until the event loop is free to continue firing.

Here’s an example (first hit freeze, then try hitting the other button or resizing the textarea):

See the Pen
Event Blocking – No Worker
by Alex MacArthur (@alexmacarthur)
on CodePen.

In his post he lays out a way of offloading that long running task into a Web Worker.

For the Sake of Your Event Listeners, Use Web Workers →

πŸ’β€β™‚οΈ Be sure to check out the mentioned workerize, as that’s easier to grasp when compared to the postMessage code.

let worker = workerize(`
	export function add(a, b) {
		// block for half a second to demonstrate asynchronicity
		let start = Date.now();
		while (Date.now()-start < 500);
		return a + b;
	}
`);

(async () => {
	console.log('3 + 9 = ', await worker.add(3, 9));
	console.log('1 + 2 = ', await worker.add(1, 2));
})();