🪔
Next.jsでWeb-Workerを呼び出す
Next.jsとWeb-Worker
Next.jsは様々な機能を無設定で行えるように開発されています
Web-Workerに関しても同様で、next.config.jsに一切手を入れずに動かすことが出来ます
どのぐらい手軽に利用可能か、試してみたいと思います
サンプル置き場
https://github.com/SoraKumo001/next-worker
https://next-worker.vercel.app/
初期作業
yarn add next react react-dom
yarn add -D typescript @types/node @types/react
ソースコード
- src/libs/sums.ts
1からcountで与えられた数までの合計を出すプログラムです
負荷をかけるため作業を1000回繰り返し、最後の結果を返します
export default null; //TypeScript警告避け
const worker = self as unknown as Worker;
worker.addEventListener("message", ({ data: { count } }: MessageEvent<{ count: number }>) => {
let a: number;
for (let j = 0; j < 1000; j++) {
a = 0;
for (let i = 1; i <= count; i++) {
a += i;
}
}
worker.postMessage({ value: a });
});
- src/pages/index.tsx
実行ボタンを押すごとにWeb-Workerを起動して、結果が返ってきたら表示を更新します
import { useState } from "react";
const Page = () => {
const [values, setValues] = useState([]);
const handleSubmit: React.FormEventHandler<HTMLFormElement> = (e) => {
e.preventDefault();
const index = values.length;
setValues([...values, "実行中"]);
//web-workerの呼び出し
const worker = new Worker(new URL("../libs/sums", import.meta.url));
worker.addEventListener("message", ({ data: { value } }) => {
setValues((values) => values.map((v, i) => (i === index ? value : v)));
});
worker.postMessage({ count: parseInt(e.currentTarget["count"].value) });
};
return (
<div>
<form onSubmit={handleSubmit}>
<input name="count" defaultValue="1000000" />
<button>実行</button>
</form>
{values.map((v, index) => (
<div key={index}>{v}</div>
))}
</div>
);
};
export default Page;
実行
yarn next
この処理を普通に行うと計算中はUIがブロックされますが、Web-Workerを利用した場合スムーズに動きます
まとめ
データのやりとりにpostMessageを介すことになるので、多少回りくどい部分がありますが、サーバと通信するのと感覚的には同じです
とてもお手軽に利用出来るので、ちょっとした重い処理がある場合などに利用していきたいところです
Discussion