😎
ReactでWebWorkerをサクッと使う
はじめに
業務やちゃんと開発したいものではなく、技術を試したりするときにworker-loader等の導入、TypeScriptでの対応をやるのが面倒だった。
サクッと使いたいだけなのに...という時に使うためだけです。
※ 業務や複数人の開発、お遊び等ではない個人開発ではちゃんとworker-loaderやcomlinkの導入・TypeScriptで型安全な開発をしましょう。
実装
WebWorkerの用意
まずはWeb Workerの実装から。
適当に受け取った数値分のループを行います。
loop.worker.js
export default () => {
self.onmessage = (event) => {
const max = event.data;
for (let i = 1; i <= max; i++) {
console.log(`${i}回目`);
}
postMessage('finish');
}
}
WebWorkerを読み込む
上記で作成したWorkerを読み込むクラスを作ります。
worker-loader.js
export defautlt class WorkerLoader extends Worker {
constructor(worker, onMessage) {
const code = worker.toString();
const blob = new Blob([`(${code})()`]);
const workerUrl = URL.createObjectURL(blob);
const instance = new Worker(workerUrl);
if (instance) {
URL.revokeObjectURL(workerUrl);
}
if (onMessage) {
instance.onmessage = onMessage;
}
return instance;
}
}
vanilla JSで使う
index.js
import WorkerLoader from './lib/worker-loader.js';
import LoopWorker from './workers/loop.worker.js';
(function () {
const loopWorker = new WorkerLoader(LoopWorker, (message) => {
console.log(`message from worker => ${message.data}`);
});
loopWorker.postMessage(100000);
})()
Reactで使う
App.jsx
import WorkerLoader from './lib/worker-loader';
import LoopWorker from './workers/loop.worker';
const App = () => {
const worker = new WorkerLoader(LoopWorker);
const handleClick = () => {
worker.postMessage(100000);
}
useEffect(() => {
worker.onmessage = (message) => {
console.log(`message from worker => ${message.data}`);
}
return () => {
worker.terminate();
}
}, []);
return <button onClick={handleClick}>post message</button>;
}
Discussion