React Suspense for Web Worker with Comlink
This is an experimental library to support Web Workers with React Suspense. Currently, it's implemented with Comlink. Comlink is promise based, but a value wrapped by this library can be treated as a normal value without async/await.
Known issues:
- No way to clear cache
- Class not supported (yet)
- (...and maybe more)
npm install react-suspense-worker
slow_fib.worker.js:
import { expose } from 'react-suspense-worker';
const fib = i => (i <= 1 ? i : fib(i - 1) + fib(i - 2));
expose(fib);
App.jsx:
import { wrap } from 'react-suspense-worker';
const fib = wrap(new Worker(new URL('./slow_fib.worker', import.meta.url)));
const DisplayFib = ({ number }) => {
const result = fib(number);
return <div>result: {result}</div>;
};
const Main = () => {
const [number, setNumber] = useState(1);
const [isPending, startTransition] = useTransition();
const onClick = () => {
startTransition(() => {
setNumber((c) => c + 1);
});
};
return (
<div>
<span>number: {number}</span>
<button type="button" onClick={onClick}>+1</button>
{isPending && 'Pending...'}
<DisplayFib number={number} />
</div>
);
};
const App = () => (
<Suspense fallback={<span>Loading...</span>}>
<Main />
</Suspense>
);
Expose a value in worker thread to be wrapped in main thread
import { expose } from 'react-suspense-worker';
const fib = (i) => (i <= 1 ? i : fib(i - 1) + fib(i - 2));
expose(fib);
Wrap a worker to be used with React Suspense
ep
Endpoint
import { wrap } from 'react-suspense-worker';
const fib = wrap(new Worker(new URL('./slow_fib.worker', import.meta.url)));
const DisplayFib = ({ number }) => {
const result = fib(number);
return <div>result: {result}</div>;
};
Returns T
The examples folder contains working examples. You can run one of them with
PORT=8080 npm run examples:01_minimal
and open http://localhost:8080 in your web browser.