
【JavaScript入門】Web Worker
Web Worker はブラウザに “もう一本の JavaScript スレッド” を生み出し、
UI スレッド(メイン)をブロックせずに 重い計算や長時間タスク を並行実行できます。
Worker とは postMessage
でデータを送り、onmessage
で受け取る ― たった 2 つの API が核です。本章では API 概観 → ファイル配置 → 動くサンプル の順に学びます。

1.基本 API
機能 | メインスレッド | Worker スレッド |
---|---|---|
インスタンス生成 | const w = new Worker("worker.js"); | ― |
メッセージ送信 | w.postMessage(data); | postMessage(data); |
受信ハンドラ | w.onmessage = e => {…} | onmessage = e => {…} |
終了 | w.terminate(); | close(); |
※ メッセージは コピー渡し(シリアライズ)になるため、同じオブジェクト参照は共有されません。
どんなとき便利?
- 画像・音声・動画のフィルタリング
- 暗号化/データ圧縮など CPU 集約タスク
- 大量ループでの統計・シミュレーション
2.サンプル構成
app3/
├─ web-worker/
│ ├─ worker-demo.html ← メイン側
│ └─ calc-worker.js ← Worker スレッド
└─ index.js ← Express サーバー("Fetch APIで通信をする"で使用したものと同じ)
3.calc-worker.js
(Worker 側)
// メッセージ受信
onmessage = e => {
const n = e.data; // 受け取った数値
// 重い計算: n 番目までの素数を列挙
const primes = [];
let num = 2;
while (primes.length < n) {
if (primes.every(p => num % p !== 0)) primes.push(num);
num++;
}
postMessage(primes); // 結果を返す
};
4.worker-demo.html
(メイン側)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>⚙️ Web Worker デモ</title>
<style>
body{font-family:"Segoe UI",sans-serif;margin:2rem;background:#f7fbff}
h1{text-align:center;font-size:1.8rem;margin-bottom:1rem}
input,button{padding:.5rem .8rem;margin-right:.5rem}
#log{white-space:pre-line;border:1px solid #ccc;background:#fff;
border-radius:8px;padding:1rem;margin-top:1rem;min-height:6rem}
</style>
</head>
<body>
<h1>⚙️ Web Worker デモ</h1>
<input id="count" type="number" value="10" min="1" />
<button id="runBtn">素数を計算</button>
<div id="log">ここに結果が表示されます</div>
<script>
const log = txt => document.getElementById("log").textContent += txt + "\n";
const worker = new Worker("calc-worker.js"); // Worker 作成
// Worker から結果を受信
worker.onmessage = e => {
log("▶ 結果: " + e.data.join(", "));
};
// ボタン: 計算指示を送る
document.getElementById("runBtn").onclick = () => {
const n = Number(document.getElementById("count").value);
log(`● 素数 ${n} 個を計算中…`);
worker.postMessage(n); // メインは止まらない
};
</script>
</body>
</html>
4.1. index.js の作成
以下の index.js を作成して、例えば「C:\Users\<ユーザー名>\Desktop\node-js\app3」に保存します。
ファイル名: index.js
// index.js
const express = require("express");
const app = express();
// ルート
app.get("/", (_, res) => res.send("Hello World"));
// 静的ファイル(/net, /web-worker 配下)
[
{ path: "/net", root: __dirname + "/net" },
{ path: "/web-worker", root: __dirname + "/web-worker" }
].forEach(opt => app.use(opt.path, express.static(opt.root)));
app.listen(3000, () => console.log("Server started: http://localhost:3000/"));
4.2. PowerShell を起動し、index.js を置いたフォルダへ移動します。
移動例:
PS C:\Users\joeac\Desktop\node-js\app3>
4.3. ターミナルで node .
を実行
node .
4.4. ブラウザのURLに「http://localhost:3000/web-worker/worker-demo.html 」を入力
すると 「Hello World」が表示されます。
ブラウザの出力例
ブラウザのURLに「http://localhost:3000/web-worker/worker-demo.html」と入力します。

● 素数 10 個を計算中…
▶ 結果: 2, 3, 5, 7, 11, 13, 17, 19, 23, 29
ページはボタン連打や入力操作を受け付け続け、
重い計算はバックグラウンドで完了後に結果だけ返ってきます。
5.ポイント解説
テーマ | 解説 |
---|---|
ファイル配置 | Worker は 同一オリジン の別 JS ファイルとして保存し、new Worker("path") で読み込む(ローカルファイル直開きでは動かないため Express などでサーバー起動が必要) |
データ転送 | postMessage はコピー渡し。大量データには structuredClone() や Transferable オブジェクト(ArrayBuffer など)を利用すると高速 |
エラー処理 | worker.onerror = e => ... でスレッド内例外を捕捉 |
終了 | 長期利用しない場合は worker.terminate() でスレッドを開放 |
まとめ
Web Worker を利用すると 計算負荷を UI スレッドから切り離し スムーズな操作感を保てます。
new Worker()
で専用スレッド生成postMessage
/onmessage
でデータ連携- メモリ共有はなくコピーが行われる
という3点を押さえれば、画像加工やデータ解析など “重たい処理” を安心してバックグラウンド実行できます。まずは本サンプルを動かし、メイン UI が固まらないことを体感してみましょう。